epoll 多线程 服务器

ExpandedBlockStart.gif 服务器
  1  //  
  2  //  a simple agi server using epoll in linux
  3  //  
  4  //  2010-12-20
  5  //  by nsy
  6  //
  7  #include  < sys / socket.h >
  8  #include  < sys / epoll.h >
  9  #include  < netinet / in .h >
 10  #include  < arpa / inet.h >
 11  #include  < fcntl.h >
 12  #include  < unistd.h >
 13  #include  < stdio.h >
 14  #include  < stdlib.h >
 15  #include  < errno.h >
 16  #include  < string .h >
 17  #include  " CallSvr.h "
 18  #include  < pthread.h >
 19  #include  " epoll.h "
 20 
 21  // test
 22  #include  " msg.h "
 23 
 24  //  set event
 25  void  EventSet( struct  myevent_s  * ev,  int  fd, int  status)
 26  {
 27    ev -> fd  =  fd;
 28    ev -> status  =  status;
 29    ev -> last_active  =  time(NULL);
 30    fprintf(stderr, " function=%s,line=%d,fd=%d\n " ,__func__,__LINE__,fd);
 31  }
 32  //  add/mod an event to epoll
 33  void  EventAdd( int  epollFd,  int  events, struct  myevent_s  * ev)
 34  {
 35     struct  epoll_event epv  =  { 0 , { 0 }};
 36     int  op;
 37    epv.data.ptr  =  ev;
 38    epv.events  =  events;
 39     if (ev -> status  ==   1 ){
 40      op  =  EPOLL_CTL_MOD;
 41      fprintf(stderr, " mod:function=%s,line=%d,fd=%d,status=%d\n " ,__func__,__LINE__,ev -> fd,ev -> status);
 42    }
 43     else {
 44      op  =  EPOLL_CTL_ADD;
 45      ev -> status  =   1 ;
 46      fprintf(stderr, " add:function=%s,line=%d,fd=%d,status=%d\n " ,__func__,__LINE__,ev -> fd,ev -> status);
 47    }
 48     if (epoll_ctl(epollFd, op, ev -> fd,  & epv)  <   0 )
 49      {
 50        fprintf(stderr, " failed:function=%s,line=%d,fd=%d:errno=%d\n " ,__func__,__LINE__,ev -> fd,errno);
 51      }
 52     else
 53      {
 54        fprintf(stderr, " success:function=%s,line=%d,fd=%d\n " ,__func__,__LINE__,ev -> fd);
 55      }
 56  }
 57  //  delete an event from epoll
 58  void  EventDel( int  epollFd, struct  myevent_s  * ev)
 59  {
 60     struct  epoll_event epv  =  { 0 , { 0 }};
 61     if (ev -> status  !=   1 return ;
 62    epv.data.ptr  =  ev;
 63    ev -> status  =   0 ;
 64    epoll_ctl(epollFd, EPOLL_CTL_DEL, ev -> fd,  & epv);
 65    fprintf(stderr, " function=%s,line=%d,fd=%d\n " ,__func__,__LINE__,ev -> fd);
 66  }
 67 
 68  //  receive data
 69  void  RecvData( struct  myevent_s  * ev)
 70  {
 71    msg_header header;
 72     int  recvbytes;
 73     if  ((recvbytes = recv(ev -> fd,  & header,  sizeof (msg_header),  0 ))  ==- 1
 74      {
 75        fprintf(stderr, " RecvHeaderErr:function=%s,line=%d,fd=%d\n " ,__func__,__LINE__,ev -> fd);
 76         goto  errret;
 77      }
 78     if (recvbytes  ==   sizeof (msg_header))
 79      {
 80         switch (header.msg_type)
 81      {
 82       case  msg_lost:
 83        {
 84          rq_lost rq;
 85           if  ((recvbytes = recv(ev -> fd, (( char * )( & rq)) + sizeof (msg_header),  sizeof (rq_lost) - sizeof (msg_header),  0 ))  ==- 1 )
 86            {
 87          fprintf(stderr, " RecvAfter:function=%s,line=%d,fd=%d\n " ,__func__,__LINE__,ev -> fd);
 88           goto  errret;
 89            }
 90           else   if (recvbytes  >   0 )
 91            {                
 92          printf( " recv sucess%d,hope to recv %d\n " ,recvbytes, sizeof (rq_lost) - sizeof (msg_header));
 93          printf( " cardno is '%s'\n " ,rq.cardno);
 94          printf( " password is '%s'\n " ,rq.password);
 95      
 96           // init ev recv
 97          memcpy( & ev -> header, & header, sizeof (msg_header));
 98          memcpy( & ev -> recv_buff, & rq, sizeof (rq_lost));
 99          ev -> recv_len  =  recvbytes;
100          fprintf(stderr, " addtologicqueue:function=%s,line=%d,fd=%d\n " ,__func__,__LINE__,ev -> fd);
101           // add to logic queue
102          sem_wait( & bin_sem_logic_data_produce);
103           struct  QUEUE_LOGIC_DATA_ITEM  * item;
104          item  =  malloc( sizeof ( struct  QUEUE_LOGIC_DATA_ITEM));
105          item -> ev  =  ev;
106          pthread_mutex_lock( & queue_logic_data_mutex);
107          TAILQ_INSERT_TAIL( & queue_logic_data_header,item,logic_data_entries);
108          pthread_mutex_unlock( & queue_logic_data_mutex);
109          sem_post( & bin_sem_logic_data_consume);
110          fprintf(stderr, " addtologicqueue--end:function=%s,line=%d,fd=%d\n " ,__func__,__LINE__,ev -> fd);
111            } else
112            {
113          fprintf(stderr, " RecvAfter:function=%s,line=%d,fd=%d:errno=%d\n " ,__func__,__LINE__,ev -> fd,errno);
114           goto  errret;
115            }
116           break ;
117        }
118      }
119         return ; // switch end function end
120      } else
121      {
122        fprintf(stderr, " function=%s,line=%d,fd=%d\n " ,__func__,__LINE__,ev -> fd);
123         goto  errret;
124      }
125   errret:
126    EventDel(g_epollFd, ev);
127    close(ev -> fd);
128  }
129  //  send data
130  void  SendData( struct  myevent_s  * ev)
131  {
132    fprintf(stderr, " JustIn:function=%s,line=%d,fd=%d\n " ,__func__,__LINE__,ev -> fd);
133     int  len;
134     //  send data
135    len  =  send(ev -> fd, ev -> send_buff, ev -> send_len,  0 );
136    ev -> send_len  =   0 ;
137    fprintf(stderr, " sendlen=%d:function=%s,line=%d,fd=%d\n " ,len,__func__,__LINE__,ev -> fd);
138     if (len  <   0 )   
139      {
140        close(ev -> fd);
141        fprintf(stderr, " err=%d:function=%s,line=%d,fd=%d\n " ,errno,__func__,__LINE__,ev -> fd);
142      } else
143      {
144         // let system known can recv
145        EventAdd(g_epollFd, EPOLLIN | EPOLLET,ev);
146      }
147  }
148 
149  void   * accept_thread_work( void   * arg)
150  {
151     while ( 1 )
152      {
153         int *  plistenFd  =  ( int * )arg;
154        fprintf(stderr, " function=%s,line=%d,listenfd=%d\n " ,__func__,__LINE__, * plistenFd);
155         struct  sockaddr_in sin;
156        socklen_t len  =   sizeof ( struct  sockaddr_in);
157         int  nfd, i;
158         //  accept
159         if ((nfd  =  accept( * plistenFd, ( struct  sockaddr * ) & sin,  & len))  ==   - 1 )
160      {
161         if (errno  !=  EAGAIN  &&  errno  !=  EINTR)
162          {
163            fprintf(stderr, " %s: bad accept " , __func__);
164          }
165         continue ;
166      }
167         do
168      {
169         for (i  =   0 ; i  <  MAX_EVENTS; i ++ )
170          {
171             if (g_Events[i].status  ==   0 )
172          {
173            fprintf(stderr, " function=%s,line=%d,listenfd=%d,currentindex=%d\n " ,__func__,__LINE__, * plistenFd,i);
174             break ;
175          }
176          }
177         if (i  ==  MAX_EVENTS)
178          {
179            fprintf(stderr, " max events:function=%s,line=%d,listenFd=%d\n " ,__func__,__LINE__, * plistenFd);
180             break ;
181          }
182         //  set nonblocking
183        fprintf(stderr, " set nonblocking:function=%s,line=%d,listenfd=%d\n " ,__func__,__LINE__, * plistenFd);
184         if (fcntl(nfd, F_SETFL, O_NONBLOCK)  <   0 break ;
185         //  add a read event for receive data
186        EventSet( & g_Events[i], nfd, 0 );
187        EventAdd(g_epollFd, EPOLLIN | EPOLLET,  & g_Events[i]);
188        fprintf(stderr, " new conn[%s:%d][time:%d]\n " , inet_ntoa(sin.sin_addr), ntohs(sin.sin_port),( int ) g_Events[i].last_active);
189      } while ( 0 );
190      }
191     return  NULL;
192  }
193 
194  void   * epoll_wait_thread_work( void   * arg)
195  {
196    fprintf(stderr, " justin:function=%s,line=%d\n " ,__func__,__LINE__);
197     //  event loop
198     struct  epoll_event events[MAX_EVENTS];
199 
200     int  checkPos  =   0 ;
201     while ( 1 ){
202       //  a simple timeout check here, every time 100, better to use a mini-heap, and add timer event
203       long  now  =  time(NULL);
204       int  i;
205       for (i  =   0 ; i  <   100 ; i ++ , checkPos ++ //  doesn't check listen fd
206        {
207       if (checkPos  ==  MAX_EVENTS) checkPos  =   0 //  recycle
208       if (g_Events[checkPos].status  !=   1 continue ;
209       long  duration  =  now  -  g_Events[checkPos].last_active;
210       if (duration  >=   60 //  60s timeout
211        {
212          close(g_Events[checkPos].fd);
213          fprintf(stderr, " [fd=%d] timeout[%d--%d].\n " ,( int ) g_Events[checkPos].fd,( int ) g_Events[checkPos].last_active, ( int )now);
214          EventDel(g_epollFd,  & g_Events[checkPos]);
215        }
216        }
217       //  wait for events to happen
218       int  fds  =  epoll_wait(g_epollFd, events, MAX_EVENTS,  1000 );
219       if (fds  <   0 ){
220        fprintf(stderr, " epoll_wait error, exit\n " );
221         break ;
222      }
223       for (i  =   0 ; i  <  fds; i ++ ){
224         struct  myevent_s  * ev  =  ( struct  myevent_s * )events[i].data.ptr;
225         if (events[i].events & EPOLLIN)  //  read event
226      {
227        sem_wait( & bin_sem_recv_fd_produce);
228        fprintf(stderr, " readEvent:function=%s,line=%d:fd=%d\n " ,__func__,__LINE__,ev -> fd);
229         // ev->call_back(ev->fd, events[i].events, ev->arg);
230         struct  QUEUE_RECV_FD_ITEM  * item;
231        item  =  malloc( sizeof ( struct  QUEUE_RECV_FD_ITEM));
232        item -> ev  =  ev;
233        pthread_mutex_lock( & queue_recv_fd_mutex);
234        TAILQ_INSERT_TAIL( & queue_recv_fd_header,item,recv_fd_entries);
235        pthread_mutex_unlock( & queue_recv_fd_mutex);
236        sem_post( & bin_sem_recv_fd_consume);
237      } else   if (events[i].events & EPOLLOUT)  //  write event
238      {
239        sem_post( & bin_sem_send_fd_consume);
240        fprintf(stderr, " post send fd consume:function=%s,line=%d:fd=%d\n " ,__func__,__LINE__,ev -> fd);
241      }
242      }
243    }
244     return  NULL;
245  }
246 
247  void   * recv_data_thread_work( void   * arg)
248  {
249     while ( 1 )
250      {
251        sem_wait( & bin_sem_recv_fd_consume);
252        fprintf(stderr, " justin:function=%s,line=%d\n " ,__func__,__LINE__);
253         int  index  =  ( int )arg;
254        fprintf(stderr, " recv thread id is %d\n " ,index);
255        pthread_mutex_lock( & queue_recv_fd_mutex);
256         struct  QUEUE_RECV_FD_ITEM  * item;
257        item  =  TAILQ_FIRST( & queue_recv_fd_header);
258        TAILQ_REMOVE( & queue_recv_fd_header,item,recv_fd_entries); 
259        pthread_mutex_unlock( & queue_recv_fd_mutex);
260        RecvData(item -> ev);
261      }
262     return  NULL;
263  }
264 
265  void   * send_data_thread_work( void   * arg)
266  {
267     while ( 1 )
268      {  
269        sem_wait( & bin_sem_send_fd_consume);
270        fprintf(stderr, " justin:function=%s,line=%d\n " ,__func__,__LINE__);
271        pthread_mutex_lock( & queue_send_fd_mutex);
272         struct  QUEUE_SEND_FD_ITEM  * item;
273        item  =  TAILQ_FIRST( & queue_send_fd_header);
274        TAILQ_REMOVE( & queue_send_fd_header,item,send_fd_entries); 
275        pthread_mutex_unlock( & queue_send_fd_mutex);
276        SendData(item -> ev);
277      }
278     return  NULL;
279  }
280 
281  void   * logic_data_thread_work( void   * arg)
282  {
283     while ( 1 )
284      {
285         // remove logic queue
286        sem_wait( & bin_sem_logic_data_consume);
287         // for test
288         int  index  =  ( int )arg;
289        fprintf(stderr, " logic thread id is %d\n " ,index);
290 
291        pthread_mutex_lock( & queue_logic_data_mutex);
292         struct  QUEUE_LOGIC_DATA_ITEM  * item;
293        item  =  TAILQ_FIRST( & queue_logic_data_header);
294        TAILQ_REMOVE( & queue_logic_data_header,item,logic_data_entries); 
295        pthread_mutex_unlock( & queue_logic_data_mutex);
296         // logic header
297         switch (item -> ev -> header.msg_type)
298      {
299       case  msg_lost:
300        {
301          rq_lost *  rq  =  (rq_lost * )item -> ev -> recv_buff;
302          
303          rs_lost rs;
304          rs.header.msg_type  =  msg_lost;
305          rs.header.size  =   sizeof (rs_lost);
306          rs.header.length  =   0 ;
307 
308           if (strcmp(rq -> cardno, " 12345 " ) == 0 )
309            {
310          rs.is_ok  =   1 ;                        
311            }
312           else
313            {
314          rs.is_ok  =   0 ;
315            }
316          memcpy( & item -> ev -> header, & rs.header, sizeof (msg_header));
317          item -> ev -> send_len  =   sizeof (rs);
318          memcpy(item -> ev -> send_buff, & rs, sizeof (rs));
319           break ;
320        }
321      }
322     
323         // add to send fd queue
324        sem_wait( & bin_sem_send_fd_produce);
325        fprintf(stderr, " after wait send fd produce\n " );
326         struct  QUEUE_SEND_FD_ITEM  * sendItem;
327        sendItem  =  malloc( sizeof ( struct  QUEUE_SEND_FD_ITEM));
328        sendItem -> ev  =  item -> ev;
329        pthread_mutex_lock( & queue_send_fd_mutex);
330        TAILQ_INSERT_TAIL( & queue_send_fd_header,sendItem,send_fd_entries);
331        pthread_mutex_unlock( & queue_send_fd_mutex);
332         // let system known can send
333        EventAdd(g_epollFd, EPOLLOUT | EPOLLET, item -> ev);
334      }
335     return  NULL;
336  }
337 
338  int  main( int  argc,  char   ** argv)
339  {
340     int  res;
341     // recv fd queue
342    TAILQ_INIT( & queue_recv_fd_header);
343    res  =  sem_init( & bin_sem_recv_fd_consume, 0 , 0 );
344     if (res)
345      {
346        fprintf(stderr, " sem init consume failed\n " );
347        exit(EXIT_FAILURE);
348      }
349 
350    res  =  sem_init( & bin_sem_recv_fd_produce, 0 ,MAX_EVENTS);
351     if (res)
352      {
353        fprintf(stderr, " sem init produce failed\n " );
354        exit(EXIT_FAILURE);
355      }
356 
357    res  =  pthread_mutex_init( & queue_recv_fd_mutex,NULL);
358     if (res != 0 )
359      {
360        perror( " create mutex for queue recv failed\n " );
361        exit(EXIT_FAILURE);
362      }
363     // logic data queue
364    TAILQ_INIT( & queue_logic_data_header);
365    res  =  sem_init( & bin_sem_logic_data_consume, 0 , 0 );
366     if (res)
367      {
368        fprintf(stderr, " sem init logic data consume failed\n " );
369        exit(EXIT_FAILURE);
370      }
371 
372    res  =  sem_init( & bin_sem_logic_data_produce, 0 ,MAX_EVENTS);
373     if (res)
374      {
375        fprintf(stderr, " sem init logic data produce failed\n " );
376        exit(EXIT_FAILURE);
377      }
378 
379    res  =  pthread_mutex_init( & queue_logic_data_mutex,NULL);
380     if (res != 0 )
381      {
382        perror( " create mutex for queue logic data failed\n " );
383        exit(EXIT_FAILURE);
384      }
385 
386     // send fd queue
387    TAILQ_INIT( & queue_send_fd_header);
388    res  =  sem_init( & bin_sem_send_fd_consume, 0 , 0 );
389     if (res)
390      {
391        fprintf(stderr, " sem init send fd consume failed\n " );
392        exit(EXIT_FAILURE);
393      }
394 
395    res  =  sem_init( & bin_sem_send_fd_produce, 0 ,MAX_EVENTS);
396     if (res)
397      {
398        fprintf(stderr, " sem init send fd produce failed\n " );
399        exit(EXIT_FAILURE);
400      }
401 
402    res  =  pthread_mutex_init( & queue_send_fd_mutex,NULL);
403     if (res != 0 )
404      {
405        perror( " create mutex for queue send fd failed\n " );
406        exit(EXIT_FAILURE);
407      }
408 
409     short  port  =   3342 //  default port
410     if (argc  ==   2 ){
411      port  =  atoi(argv[ 1 ]);
412    }
413     //  create epoll
414    g_epollFd  =  epoll_create(MAX_EVENTS);
415     if (g_epollFd  <=   0
416      {
417        fprintf(stderr, " create epoll failed:fd=%d:function=%s,line=%d\n " , g_epollFd,__func__,__LINE__);
418        exit(EXIT_FAILURE);
419      }
420     //  create & bind listen socket
421     int  listenFd  =  socket(AF_INET, SOCK_STREAM,  0 );
422     //  bind & listen
423     struct  sockaddr_in sin;
424    bzero( & sin,  sizeof (sin));
425    sin.sin_family  =  AF_INET;
426    sin.sin_addr.s_addr  =  INADDR_ANY;
427    sin.sin_port  =  htons(port);
428    bind(listenFd, ( const   struct  sockaddr * ) & sin,  sizeof (sin));
429    listen(listenFd,  5 );
430    fprintf(stderr, " server running:port[%d]\n " , port);
431     // create accept thread
432 
433     void   * thread_result;
434    pthread_t accept_t;  
435    res  =  pthread_create( & accept_t,NULL,accept_thread_work,( void   * ) & listenFd);
436     if (res  !=   0 )
437      {
438        perror( " accept create failed\n " );
439        exit(EXIT_FAILURE);
440      }
441 
442     // create epoll wait thread
443    pthread_t epoll_wait_t;
444    res  =  pthread_create( & epoll_wait_t,NULL,epoll_wait_thread_work,NULL);
445     if (res  !=   0 )
446      {
447        perror( " create epoll wait thread failed\n " );
448        exit(EXIT_FAILURE);
449      }
450     // create two recv data thread
451    pthread_t recv_data_t;
452    res  =  pthread_create( & recv_data_t,NULL,recv_data_thread_work,( void * ) 1 );
453     if (res != 0 )
454      {
455        perror( " create recv data thread failed\n " );
456        exit(EXIT_FAILURE);
457      }
458 
459    pthread_t recv_data_t_1;
460    res  =  pthread_create( & recv_data_t_1,NULL,recv_data_thread_work,( void * ) 2 );
461     if (res != 0 )
462      {
463        perror( " create recv data thread failed\n " );
464        exit(EXIT_FAILURE);
465      }
466     // create two send data thread
467    pthread_t send_data_t;
468    res  =  pthread_create( & send_data_t,NULL,send_data_thread_work,( void * ) 1 );
469     if (res != 0 )
470      {
471        perror( " create send data thread failed\n " );
472        exit(EXIT_FAILURE);
473      }
474 
475    pthread_t send_data_t_1;
476    res  =  pthread_create( & send_data_t_1,NULL,send_data_thread_work,( void * ) 2 );
477     if (res != 0 )
478      {
479        perror( " create send data thread failed\n " );
480        exit(EXIT_FAILURE);
481      }
482 
483     // create two logic work thread
484    pthread_t logic_work_t;
485    res  =  pthread_create( & logic_work_t,NULL,logic_data_thread_work,( void * ) 1 );
486     if (res != 0 )
487      {
488        perror( " create logic work thread failed\n " );
489        exit(EXIT_FAILURE);
490      }
491 
492   pthread_t logic_work_t_1;
493    res  =  pthread_create( & logic_work_t_1,NULL,logic_data_thread_work,( void * ) 2 );
494     if (res != 0 )
495      {
496        perror( " create logic work thread failed\n " );
497        exit(EXIT_FAILURE);
498      }
499 
500     // wait child thread
501    res  =  pthread_join(accept_t, & thread_result);
502     if (res != 0 )
503      {
504        perror( " accept thread join failed\n " );
505        exit(EXIT_FAILURE);
506      }
507 
508     // wait child thread
509    res  =  pthread_join(epoll_wait_t, & thread_result);
510     if (res != 0 )
511      {
512        perror( " epoll wait thread join failed\n " );
513        exit(EXIT_FAILURE);
514      }
515 
516     // wait child thread
517    res  =  pthread_join(recv_data_t, & thread_result);
518     if (res != 0 )
519      {
520        perror( " recv data thread join failed\n " );
521        exit(EXIT_FAILURE);      
522      }
523     // wait child thread
524    res  =  pthread_join(recv_data_t_1, & thread_result);
525     if (res != 0 )
526      {
527        perror( " recv data thread join failed\n " );
528        exit(EXIT_FAILURE);      
529      }
530 
531     // wait child thread
532    res  =  pthread_join(send_data_t, & thread_result);
533     if (res != 0 )
534      {
535        perror( " send data thread join failed\n " );
536        exit(EXIT_FAILURE);      
537      }
538     // wait child thread
539    res  =  pthread_join(send_data_t_1, & thread_result);
540     if (res != 0 )
541      {
542        perror( " send data thread join failed\n " );
543        exit(EXIT_FAILURE);      
544      }
545     // wait child thread
546    res  =  pthread_join(logic_work_t, & thread_result);
547     if (res != 0 )
548      {
549        perror( " logic work thread join failed\n " );
550        exit(EXIT_FAILURE);      
551      }
552     // wait child thread
553    res  =  pthread_join(logic_work_t_1, & thread_result);
554     if (res != 0 )
555      {
556        perror( " logic work thread join failed\n " );
557        exit(EXIT_FAILURE);      
558      }
559     //  free resource
560    close(g_epollFd);
561    sem_destroy( & bin_sem_recv_fd_consume);
562    sem_destroy( & bin_sem_recv_fd_produce);
563    pthread_mutex_destroy( & queue_recv_fd_mutex);
564 
565    sem_destroy( & bin_sem_logic_data_consume);
566    sem_destroy( & bin_sem_logic_data_produce);
567    pthread_mutex_destroy( & queue_logic_data_mutex);
568 
569    sem_destroy( & bin_sem_send_fd_consume);
570    sem_destroy( & bin_sem_send_fd_produce);
571    pthread_mutex_destroy( & queue_send_fd_mutex);
572     return   0 ;
573
ExpandedBlockStart.gif 服务器头
 1  #ifndef _epoll_h_
 2  #define  _epoll_h_
 3 
 4  #include  " sys/queue.h "
 5  #include  < semaphore.h >
 6  #include  " msg.h "
 7 
 8  #define  MAX_EVENTS 500
 9 
10  int  g_epollFd;
11 
12  void   * accept_thread_work( void   * arg);
13  void   * epoll_wait_thread_work( void   * arg);
14  void   * recv_data_thread_work( void   * arg);
15  void   * send_data_thread_work( void   * arg);
16  void   * logic_data_thread_work( void   * arg);
17 
18  struct  myevent_s
19  {
20     int  fd;
21     int  status;  //  1: in epoll wait list, 0 not in
22    msg_header header;
23     char  recv_buff[ 256 ];  //  recv data buffer
24     int  recv_len;
25     char  send_buff[ 256 ]; // send data buffer
26     int  send_len;
27     long  last_active;  //  last active time
28  };
29 
30  struct  myevent_s g_Events[MAX_EVENTS + 1 ];  //  g_Events[MAX_EVENTS] is used by listen fd
31 
32  // recv fd queue
33  struct  QUEUE_RECV_FD_ITEM{
34     struct  myevent_s *  ev;
35    TAILQ_ENTRY(QUEUE_RECV_FD_ITEM) recv_fd_entries;
36  };
37 
38  TAILQ_HEAD(,QUEUE_RECV_FD_ITEM) queue_recv_fd_header;
39 
40  sem_t bin_sem_recv_fd_produce;
41  sem_t bin_sem_recv_fd_consume;
42 
43  pthread_mutex_t queue_recv_fd_mutex;
44 
45  // send fd queue
46  struct  QUEUE_SEND_FD_ITEM{
47     struct  myevent_s *  ev;
48    TAILQ_ENTRY(QUEUE_SEND_FD_ITEM) send_fd_entries;
49  };
50 
51  TAILQ_HEAD(,QUEUE_SEND_FD_ITEM) queue_send_fd_header;
52 
53  sem_t bin_sem_send_fd_produce;
54  sem_t bin_sem_send_fd_consume;
55 
56  pthread_mutex_t queue_send_fd_mutex;
57 
58  // logic data buff
59  struct  QUEUE_LOGIC_DATA_ITEM{
60     struct  myevent_s *  ev;
61    TAILQ_ENTRY(QUEUE_LOGIC_DATA_ITEM) logic_data_entries;
62  };
63 
64  TAILQ_HEAD(,QUEUE_LOGIC_DATA_ITEM) queue_logic_data_header;
65 
66  sem_t bin_sem_logic_data_produce;
67  sem_t bin_sem_logic_data_consume;
68 
69  pthread_mutex_t queue_logic_data_mutex;
70 
71  #endif
72 

 

  }

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值