LCOV - code coverage report
Current view: top level - src/gwrl - event_kqueue.c (source / functions) Hit Total Coverage
Test: all.info Lines: 118 163 72.4 %
Date: 2012-09-24 Functions: 9 10 90.0 %
Branches: 32 74 43.2 %

           Branch data     Line data    Source code
       1                 :            : 
       2                 :            : #include "gwrl/event.h"
       3                 :            : 
       4                 :            : //default amount of struct kevent to pull from kevent when polling.
       5                 :            : #ifndef GWRL_KQUEUE_KEVENT_COUNT
       6                 :            : #       define GWRL_KQUEUE_KEVENT_COUNT 64
       7                 :            : #endif
       8                 :            : 
       9                 :            : //kqueue backend for gwrl->backend
      10                 :            : typedef struct _gwrlbkd_kqueue {
      11                 :            :         gwrlbkd _;                //base structure
      12                 :            :         int kq;                   //kq fd
      13                 :            :         size_t maxkevents;        //count of kevents
      14                 :            :         struct kevent * kevents;  //container for kevents
      15                 :            : } gwrlbkd_kqueue;
      16                 :            : 
      17                 :            : #ifdef __cplusplus
      18                 :            : extern "C" {
      19                 :            : #endif
      20                 :            : 
      21                 :         24 : gwrlbkd * gwrl_bkd_init(gwrl * rl) {
      22                 :         24 :         gwrlbkd_kqueue * kbkd = _gwrlbkdk(gwrl_mem_calloc(1,sizeof(gwrlbkd_kqueue)));
      23                 :            :         
      24                 :            :         #ifdef GWRL_COVERAGE_INTERNAL_ASSERT_VARS
      25                 :         24 :                 if(asserts_var1 == gwrlbkd_init_fail) {
      26                 :          1 :                         free(kbkd);
      27                 :          1 :                         kbkd = NULL;
      28                 :          1 :                 }
      29                 :            :         #endif
      30                 :            :         
      31         [ +  + ]:         24 :         if(!kbkd) {
      32                 :            :                 #ifndef GWRL_COVERAGE_INTERNAL_ASSERT_VARS
      33                 :            :                         gwerr("(3el0L) calloc error");
      34                 :            :                 #endif
      35                 :          1 :                 return NULL;
      36                 :            :         }
      37                 :            : 
      38                 :         23 :         kbkd->kq = kqueue();
      39         [ -  + ]:         23 :         if(kbkd->kq < 0) {
      40                 :          0 :                 gwerr("(1LKdoL) kqueue error");
      41                 :          0 :                 free(kbkd);
      42                 :          0 :                 return NULL;
      43                 :            :         }
      44                 :         23 :         kbkd->kevents = gwrl_mem_calloc(1,sizeof(struct kevent)*GWRL_KQUEUE_KEVENT_COUNT);
      45                 :         23 :         kbkd->maxkevents = GWRL_KQUEUE_KEVENT_COUNT;
      46                 :         23 :         rl->options.gwrl_kqueue_kevent_count = GWRL_KQUEUE_KEVENT_COUNT;
      47                 :         23 :         return _gwrlbkd(kbkd);
      48                 :         24 : }
      49                 :            : 
      50                 :          2 : void gwrl_bkd_set_options(gwrl * rl,gwrl_options * opts) {
      51                 :          2 :         gwrlbkd_kqueue * kbkd = _gwrlbkdk(rl->backend);
      52                 :          2 :         if(opts->gwrl_kqueue_kevent_count > kbkd->maxkevents) {
      53                 :          0 :                 kbkd->maxkevents = opts->gwrl_kqueue_kevent_count;
      54                 :          0 :         }
      55                 :          2 :         void * tmp = gwrl_mem_realloc(kbkd->kevents,sizeof(struct kevent) * kbkd->maxkevents);
      56         [ -  + ]:          2 :         while(!tmp) {
      57                 :          0 :                 gwerr("(54oKD0) realloc error");
      58                 :          0 :                 tmp = gwrl_mem_realloc(kbkd->kevents,sizeof(struct kevent) * kbkd->maxkevents);
      59                 :          0 :         }
      60                 :          2 :         kbkd->kevents = (struct kevent *)tmp;
      61                 :          2 : }
      62                 :            : 
      63                 :          4 : void gwrl_bkd_free(gwrl * rl) {
      64                 :          4 :         gwrlbkd_kqueue * kbkd = _gwrlbkdk(rl->backend);
      65                 :          4 :         close(kbkd->kq);
      66                 :          4 :         free(kbkd->kevents);
      67                 :          4 :         free(rl->backend);
      68                 :          4 :         rl->backend = NULL;
      69                 :          4 : }
      70                 :            : 
      71                 :         33 : void gwrl_bkd_kevent(gwrl * rl, gwrlsrc * src, int kflags, int kfilter) {
      72                 :         33 :         int res = 0;
      73                 :         33 :         struct kevent ke;
      74                 :         33 :         struct timespec ts = {0};
      75                 :         33 :         gwrlbkd_kqueue * kbkd = _gwrlbkdk(rl->backend);
      76                 :         33 :         bzero(&ke,sizeof(ke));
      77                 :         33 :         ke.ident = _gwrlsrcf(src)->fd;
      78                 :         33 :         ke.udata = src;
      79                 :         33 :         ke.flags = kflags;
      80                 :         33 :         ke.filter = kfilter;
      81                 :         33 :         res = kevent(kbkd->kq,&ke,1,NULL,0,&ts);
      82         [ #  # ]:          0 :         if(res < 0 && errno != EBADF) gwprintsyserr("(9dlkF) kevent error",errno);
      83                 :         33 : }
      84                 :            : 
      85                 :          2 : void gwrl_src_file_update_flags(gwrl * rl, gwrlsrc * src, gwrlsrc_flags_t flags) {
      86                 :            :         
      87                 :            :         //enable read
      88                 :          2 :         if(flisset(flags,GWRL_RD)) {
      89                 :          2 :                 flset(flags,GWRL_ENABLED);
      90                 :          2 :                 gwrl_bkd_kevent(rl,src,EV_ADD|EV_ENABLE,EVFILT_READ);
      91                 :            : 
      92                 :            :         //disable read
      93 [ #  # ][ #  # ]:          2 :         } else if(flisset(src->flags,GWRL_RD) && !flisset(flags,GWRL_RD)) {
      94                 :          0 :                 gwrl_bkd_kevent(rl,src,EV_ADD|EV_DISABLE,EVFILT_READ);
      95                 :          0 :         }
      96                 :            :         
      97                 :            :         //enable write
      98         [ -  + ]:          2 :         if(flisset(flags,GWRL_WR)) {
      99                 :          0 :                 flset(flags,GWRL_ENABLED);
     100                 :          0 :                 gwrl_bkd_kevent(rl,src,EV_ADD|EV_ENABLE,EVFILT_WRITE);
     101                 :          0 :         }
     102                 :            :         
     103                 :            :         //disable write
     104 [ -  + ][ #  # ]:          2 :         else if(flisset(src->flags,GWRL_WR) && !flisset(flags,GWRL_WR)) {
     105                 :          0 :                 gwrl_bkd_kevent(rl,src,EV_ADD|EV_DISABLE,EVFILT_WRITE);
     106                 :          2 :         }
     107                 :            :         
     108                 :          2 :         src->flags = flags;
     109                 :          2 : }
     110                 :            : 
     111                 :         37 : void gwrl_bkd_src_add(gwrl * rl, gwrlsrc * src) {
     112                 :         37 :         int kflags = 0;
     113                 :            : 
     114                 :         37 :         if(flisset(src->flags,GWRL_RD)) {
     115                 :         29 :                 kflags = EV_ADD;
     116         [ +  + ]:         29 :                 if(!flisset(src->flags,GWRL_ENABLED)) kflags |= EV_DISABLE;
     117                 :         29 :                 gwrl_bkd_kevent(rl,src,kflags,EVFILT_READ);
     118                 :         29 :         }
     119                 :            :         
     120         [ -  + ]:         37 :         if(flisset(src->flags,GWRL_WR)) {
     121                 :          0 :                 kflags = EV_ADD;
     122         [ #  # ]:          0 :                 if(!flisset(src->flags,GWRL_ENABLED)) kflags |= EV_DISABLE;
     123                 :          0 :                 gwrl_bkd_kevent(rl,src,kflags,EVFILT_WRITE);
     124                 :          0 :         }
     125                 :         37 : }
     126                 :            : 
     127                 :          5 : void gwrl_bkd_del_src(gwrl * rl, gwrlsrc * src) {
     128                 :          5 :         if(flisset(src->flags,GWRL_RD)) {
     129                 :          0 :                 gwrl_bkd_kevent(rl,src,EV_DELETE,EVFILT_READ);
     130                 :          0 :         }
     131                 :            :         
     132         [ -  + ]:          5 :         if(flisset(src->flags,GWRL_WR)) {
     133                 :          0 :                 gwrl_bkd_kevent(rl,src,EV_DELETE,EVFILT_WRITE);
     134                 :          0 :         }
     135                 :            :         
     136                 :          5 :         flclr(src->flags,GWRL_ENABLED);
     137                 :          5 : }
     138                 :            : 
     139                 :          0 : void gwrl_bkd_enable_src(gwrl * rl, gwrlsrc * src) {
     140                 :          0 :         if(flisset(src->flags,GWRL_RD)) {
     141                 :          0 :                 gwrl_bkd_kevent(rl,src,EV_ENABLE,EVFILT_READ);
     142                 :          0 :         }
     143                 :            :         
     144         [ #  # ]:          0 :         if(flisset(src->flags,GWRL_WR)) {
     145                 :          0 :                 gwrl_bkd_kevent(rl,src,EV_ENABLE,EVFILT_WRITE);
     146                 :          0 :         }
     147                 :            :         
     148                 :          0 :         flset(src->flags,GWRL_ENABLED);
     149                 :          0 : }
     150                 :            : 
     151                 :          2 : void gwrl_bkd_disable_src(gwrl * rl, gwrlsrc * src) {
     152                 :          2 :         if(flisset(src->flags,GWRL_RD)) {
     153                 :          2 :                 gwrl_bkd_kevent(rl,src,EV_DISABLE,EVFILT_READ);
     154                 :          2 :         }
     155                 :            :         
     156         [ -  + ]:          2 :         if(flisset(src->flags,GWRL_WR)) {
     157                 :          0 :                 gwrl_bkd_kevent(rl,src,EV_DISABLE,EVFILT_WRITE);
     158                 :          0 :         }
     159                 :            :         
     160                 :          2 :         flclr(src->flags,GWRL_ENABLED);
     161                 :          2 : }
     162                 :            : 
     163                 :        198 : void gwrl_bkd_gather(gwrl * rl) {
     164                 :        198 :         int i = 0;
     165                 :        198 :         int res = 0;
     166                 :        198 :         bool postread = false;
     167                 :        198 :         bool postwrite = false;
     168                 :        198 :         struct kevent * event;
     169                 :        198 :         struct timespec * timeout = &rl->backend->timeout;
     170                 :        198 :         gwrlsrc * src = NULL;
     171                 :        198 :         gwrlevt * evt = NULL;
     172                 :        198 :         gwrlsrc_file * fsrc = NULL;
     173                 :        198 :         gwrlbkd_kqueue * kbkd = _gwrlbkdk(rl->backend);
     174                 :            :         
     175         [ +  - ]:         13 :         if(timeout->tv_sec == sec_min && timeout->tv_nsec == nsec_min) {
     176                 :         13 :                 timeout = NULL;
     177                 :         13 :         }
     178                 :            :         
     179 [ +  + ][ +  + ]:        198 :         if(!timeout && flisset(rl->flags,GWRL_NOSLEEP)) {
     180                 :         11 :                 struct timespec ts = {0};
     181                 :         11 :                 timeout = &ts;
     182                 :         11 :         }
     183                 :            :         
     184                 :        198 :         flset(rl->flags,GWRL_SLEEPING);
     185                 :        198 :         res = kevent(kbkd->kq,NULL,0,kbkd->kevents,rl->options.gwrl_kqueue_kevent_count,timeout);
     186                 :        198 :         flclr(rl->flags,GWRL_SLEEPING);
     187                 :            :         
     188         [ +  + ]:        198 :         if(res == 0) return;
     189 [ -  + ][ #  # ]:        102 :         if(res < 0 && (errno == EINVAL || errno == EINTR)) return;
                 [ #  # ]
     190                 :            :         
     191         [ +  - ]:        102 :         if(res > 0) {
     192         [ +  + ]:        204 :                 while(i < res) {
     193                 :        102 :                         event = &kbkd->kevents[i];
     194                 :        102 :                         src = event->udata;
     195         [ -  + ]:        102 :                         if(!flisset(src->flags,GWRL_ENABLED)) continue;
     196                 :            :                         
     197         [ +  - ]:        102 :                         if(src->type == GWRL_SRC_TYPE_FILE) {
     198                 :        102 :                                 fsrc = _gwrlsrcf(src);
     199                 :            :                                 
     200         [ -  + ]:        102 :                                 if(event->flags & EV_ERROR) {
     201                 :          0 :                                         gwrl_src_disable(rl,src);
     202                 :          0 :                                         postread = true;
     203                 :          0 :                                 }
     204                 :            :                                 
     205 [ +  - ][ -  + ]:        102 :                                 if((src->flags & GWRL_RD) && (event->flags & EV_EOF)) {
     206                 :          0 :                                         postread = true;
     207 [ +  - ][ +  - ]:        102 :                                 } else if((src->flags & GWRL_RD) && (event->filter == EVFILT_READ)) {
     208                 :        102 :                                         postread = true;
     209                 :        102 :                                 }
     210                 :            :                                 
     211 [ -  + ][ #  # ]:        102 :                                 if((src->flags & GWRL_WR) && (event->filter == EVFILT_WRITE)) {
     212                 :          0 :                                         postwrite = true;
     213                 :          0 :                                 }
     214                 :            :                                         
     215         [ +  - ]:        102 :                                 if(postread) {
     216                 :        102 :                                         evt = gwrl_evt_create(rl,src,src->callback,src->userdata,fsrc->fd,GWRL_RD);
     217         [ -  + ]:        102 :                                         while(!evt) evt = gwrl_evt_create(rl,src,src->callback,src->userdata,fsrc->fd,GWRL_RD);
     218                 :        102 :                                         gwrl_post_evt(rl,evt);
     219                 :        102 :                                 }
     220                 :            :                                 
     221         [ #  # ]:          0 :                                 else if(postwrite) {
     222                 :          0 :                                         evt = gwrl_evt_create(rl,src,src->callback,src->userdata,fsrc->fd,GWRL_WR);
     223         [ #  # ]:          0 :                                         while(!evt) evt = gwrl_evt_create(rl,src,src->callback,src->userdata,fsrc->fd,GWRL_WR);
     224                 :          0 :                                         gwrl_post_evt(rl,evt);
     225                 :          0 :                                 }
     226                 :        102 :                         }
     227                 :            :                         
     228                 :        102 :                         i++;
     229                 :        102 :                 }
     230                 :        102 :         }
     231                 :        198 : }
     232                 :            : 
     233                 :            : #ifdef __cplusplus
     234                 :            : }
     235                 :            : #endif

Generated by: LCOV version 1.9