Changeset 367 for trunk/src/sh_inotify.c


Ignore:
Timestamp:
Oct 30, 2011, 9:18:31 AM (13 years ago)
Author:
katerina
Message:

Modifications for ticket #265 (inotify support). Needs testing.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/sh_inotify.c

    r364 r367  
    5151
    5252#if defined(HAVE_PTHREAD)
     53
     54SH_MUTEX_STATIC(mutex_list_dormant, PTHREAD_MUTEX_INITIALIZER);
     55SH_MUTEX_STATIC(mutex_watches,      PTHREAD_MUTEX_INITIALIZER);
     56
    5357static pthread_key_t  inotify_key;
    5458static pthread_once_t inotify_key_once = PTHREAD_ONCE_INIT;
     
    122126  int    watch;
    123127  int    flag;
     128  int    class;
     129  unsigned long check_mask;
    124130  char * file;
    125131} sh_watch;
     
    190196#define SH_INOTIFY_MODIFY 1
    191197
    192 static void sh_inotify_init(sh_watches * watches)
    193 {
     198void sh_inotify_init(sh_watches * watches)
     199{
     200  SH_MUTEX_LOCK_UNSAFE(mutex_watches);
    194201  watches->list_of_watches = NULL;
    195202  watches->count           = 0;
    196203  watches->max_count       = 0;
     204  SH_MUTEX_UNLOCK_UNSAFE(mutex_watches);
     205
     206  SH_MUTEX_LOCK_UNSAFE(mutex_list_dormant);
     207  watches->dormant_watches = NULL;
     208  SH_MUTEX_UNLOCK_UNSAFE(mutex_list_dormant);
     209
    197210  return;
     211}
     212
     213ssize_t sh_inotify_read(char * buffer, size_t count)
     214{
     215  ssize_t len;
     216  int     ifd = sh_inotify_getfd();
     217
     218  do {
     219    len = read (ifd, &buffer, count);
     220  } while (len < 0 || errno == EINTR);
     221
     222  return len;
    198223}
    199224
     
    226251};
    227252
     253static void sh_inotify_listitem_destroy(struct sh_inotify_litem * this)
     254{
     255  if (this)
     256    SH_FREE(this);
     257  return;
     258}
     259
     260/* No Mutex in the list cursor functions, must be in the caller
     261 * function...
     262 */
    228263typedef struct {
    229264  struct sh_inotify_litem *prenode;
     
    231266} sh_inotify_listCursor;
    232267
    233 static sh_watch * sh_inotify_list_first(sh_inotify_listCursor * listcursor, sh_watches * watches)
     268static sh_watch * sh_inotify_list_first(sh_inotify_listCursor * listcursor,
     269                                        sh_watches * watches)
    234270{
    235271  listcursor->prenode = watches->dormant_watches;
    236272  listcursor->curnode = watches->dormant_watches;
    237 
    238   return listcursor->curnode->watch;
    239 }
    240 
    241 static sh_watch * sh_inotify_list_next(sh_inotify_listCursor * listcursor, sh_watches * watches)
    242 {
    243   (void) watches;
    244 
    245   listcursor->prenode = listcursor->curnode;
    246   listcursor->curnode = listcursor->curnode->next;
    247273
    248274  if (listcursor->curnode)
     
    251277}
    252278
    253 static void sh_inotify_listitem_destroy(struct sh_inotify_litem * this)
    254 {
    255   SH_FREE(this);
    256   return;
    257 }
    258 
    259 static sh_watch * sh_inotify_list_del_current(sh_inotify_listCursor * listcursor, sh_watches * watches)
     279static sh_watch * sh_inotify_list_next(sh_inotify_listCursor * listcursor,
     280                                       sh_watches * watches)
     281{
     282  (void) watches;
     283
     284  listcursor->prenode = listcursor->curnode;
     285
     286  if (listcursor->curnode)
     287    {
     288      listcursor->curnode = listcursor->curnode->next;
     289      return listcursor->curnode->watch;
     290    }
     291
     292  return NULL;
     293}
     294
     295static sh_watch * sh_inotify_list_del_cur(sh_inotify_listCursor * listcursor,
     296                                          sh_watches * watches)
    260297{
    261298  sh_watch * ret = NULL;
     
    277314          listcursor->curnode       = this->next;
    278315        }
    279       ret = listcursor->curnode->watch;
     316      if (listcursor->curnode)
     317        ret = listcursor->curnode->watch;
     318      else
     319        ret = NULL;
    280320      sh_inotify_listitem_destroy(this);
    281321    }
     
    285325static int sh_inotify_add_dormant(sh_watches * watches, sh_watch * item)
    286326{
    287   struct sh_inotify_litem * this = SH_ALLOC(sizeof(struct sh_inotify_litem));
     327  struct sh_inotify_litem * this;
     328
     329  SH_MUTEX_LOCK(mutex_list_dormant);
     330  this = SH_ALLOC(sizeof(struct sh_inotify_litem));
    288331
    289332  this->watch = item;
     
    291334 
    292335  watches->dormant_watches = this;
     336  SH_MUTEX_UNLOCK(mutex_list_dormant);
    293337  return 0;
     338}
     339
     340static void * sh_dummy_popret = NULL;
     341
     342char * sh_inotify_pop_dormant(sh_watches * watches,
     343                              int * class, unsigned long * check_mask)
     344{
     345  char * popret = NULL;
     346  struct sh_inotify_litem * this;
     347
     348  /* Take the address to keep gcc from putting it into a register.
     349   * Avoids the 'clobbered by longjmp' warning.
     350   */
     351  sh_dummy_popret = (void *) &popret;
     352
     353  SH_MUTEX_LOCK(mutex_list_dormant);
     354
     355  this = (struct sh_inotify_litem *) watches->dormant_watches;
     356
     357  if (this)
     358    {
     359      *class = this->watch->class;
     360      *check_mask = this->watch->check_mask;
     361      popret = sh_util_strdup(this->watch->file);
     362
     363      watches->dormant_watches = this->next;
     364
     365      sh_inotify_free_watch(this->watch);
     366      SH_FREE(this);
     367    }
     368  SH_MUTEX_UNLOCK(mutex_list_dormant);
     369
     370  return popret;
     371}
     372
     373void sh_inotify_purge_dormant(sh_watches * watches)
     374{
     375  struct sh_inotify_litem * this;
     376
     377  SH_MUTEX_LOCK(mutex_list_dormant);
     378  this = (struct sh_inotify_litem *) watches->dormant_watches;
     379
     380  watches->dormant_watches = NULL;
     381
     382  while (this)
     383    {
     384      struct sh_inotify_litem * cur = this;
     385     
     386      this = this->next;
     387
     388      sh_inotify_free_watch(cur->watch);
     389      SH_FREE(cur);
     390    }
     391  SH_MUTEX_UNLOCK(mutex_list_dormant);
     392  return;
    294393}
    295394
     
    308407{
    309408  int     ifd = sh_inotify_getfd();
    310   zAVLTree   * all_watches = (zAVLTree *)(watches->list_of_watches);
     409  zAVLTree   * all_watches;
     410
     411  SH_MUTEX_LOCK(mutex_watches);
     412  all_watches = (zAVLTree *)(watches->list_of_watches);
    311413
    312414  if (all_watches)
    313415    zAVLFreeTree(all_watches, sh_inotify_free_watch);
    314416
    315   sh_inotify_init(watches);
     417  watches->list_of_watches = NULL;
     418  watches->count = 0;
     419  SH_MUTEX_UNLOCK(mutex_watches);
    316420
    317421  if (ifd >= 0)
    318422    close(ifd);
    319423  sh_set_inotify_fd(-1);
    320 
    321   watches->count = 0;
    322424
    323425  return;
     
    345447}
    346448
     449#define SH_INOTIFY_FILEFLAGS \
     450  (IN_ATTRIB|IN_MODIFY|IN_DELETE_SELF|IN_MOVE_SELF|IN_UNMOUNT)
     451#define SH_INOTIFY_DIRFLAGS \
     452  (SH_INOTIFY_FILEFLAGS|IN_DELETE|IN_CREATE|IN_MOVED_FROM|IN_MOVED_TO)
     453
     454#define SH_INOTIFY_FLAGS (SH_INOTIFY_FILEFLAGS|SH_INOTIFY_DIRFLAGS)
     455
     456/* Create an item and put it on the 'dormant' list for later watch creation
     457 */
     458int sh_inotify_add_watch_later(char * filename, sh_watches * watches,
     459                               int * errnum,
     460                               int class, unsigned long check_mask)
     461{
     462  sh_watch   * item;
     463
     464  item = sh_inotify_create_watch(filename, -1, /* flag */ 0);
     465
     466  item->class      = class;
     467  item->check_mask = check_mask;
     468
     469  sh_inotify_add_dormant(watches, item);
     470  if (errnum)
     471    *errnum = 0;
     472
     473  return 0;
     474}
     475         
     476int sh_inotify_rm_watch (sh_watches * watches, sh_watches * save, int wd)
     477{
     478  int ifd = sh_get_inotify_fd();
     479
     480  if (watches)
     481    {
     482      sh_watch   * item;
     483 
     484      SH_MUTEX_LOCK(mutex_watches);
     485      item = zAVLSearch(watches->list_of_watches, &wd);
     486     
     487      if (item)
     488        {
     489          zAVLDelete(watches->list_of_watches, &wd);
     490          if (save) /* optionally save the item */
     491            {
     492              item->watch = -1;
     493              sh_inotify_add_dormant(save, item);
     494            }
     495          else
     496            {
     497              sh_inotify_free_watch(item);
     498            }
     499        }
     500      SH_MUTEX_UNLOCK(mutex_watches);
     501    }
     502  return inotify_rm_watch(ifd, wd);
     503}
     504
     505#if (defined(SH_WITH_CLIENT) || defined(SH_STANDALONE))
     506static void * sh_dummy_litem;
     507
     508int sh_inotify_recheck_watches (sh_watches * watches, sh_watches * save)
     509{
     510  sh_watch   * litem;
     511  sh_inotify_listCursor listcursor;
     512  int ifd = sh_get_inotify_fd();
     513
     514  extern void sh_fInotify_report_add(char * path, int class, unsigned long check_mask);
     515
     516  sh_dummy_litem = (void*) &litem;
     517
     518  /* -- Check dormant watches for reopening.
     519   */
     520  SH_MUTEX_LOCK(mutex_list_dormant);
     521 
     522  for (litem = sh_inotify_list_first(&listcursor, save); litem;
     523       litem = sh_inotify_list_next(&listcursor, save))
     524    {
     525    have_next:
     526
     527      /* sh_inotify_list_del_cur may return NULL */
     528      if (litem && litem->file && litem->watch == -1)
     529        {
     530          litem->watch = inotify_add_watch (ifd, litem->file,
     531                                            SH_INOTIFY_FLAGS);
     532         
     533          if (litem->watch >= 0)
     534            {
     535              SH_MUTEX_LOCK(mutex_watches);
     536              if (watches->list_of_watches)
     537                zAVLInsert(watches->list_of_watches, litem);
     538              SH_MUTEX_UNLOCK(mutex_watches);
     539
     540              sh_fInotify_report_add(litem->file, litem->class, litem->check_mask);
     541
     542              litem = sh_inotify_list_del_cur(&listcursor, save);
     543             
     544              goto have_next;
     545            }
     546        }
     547    }
     548  SH_MUTEX_UNLOCK(mutex_list_dormant);
     549  return 0;
     550}
     551#endif
     552
    347553/* This function is idempotent; it will add the watch only once
    348554 */
    349 int sh_inotify_add_watch(char * filename, sh_watches * watches, int  * errnum)
    350 {
     555int sh_inotify_add_watch(char * filename, sh_watches * watches, int * errnum,
     556                         int class, unsigned long check_mask)
     557{
     558  volatile int retval = 0;
     559
     560  SH_MUTEX_LOCK(mutex_watches);
     561
    351562  *errnum = 0;
    352563
     
    375586
    376587          nwatch = inotify_add_watch (ifd, filename,
    377                                       IN_MODIFY|IN_DELETE_SELF|IN_MOVE_SELF|IN_UNMOUNT);
     588                                      SH_INOTIFY_FLAGS);
    378589          if (nwatch < 0)
    379590            {
    380591              *errnum = errno;
    381               return -1;
     592              retval = -1;
     593              goto retpoint;
    382594            }
    383595
    384596          item = sh_inotify_create_watch(filename, nwatch, /* flag */ 0);
     597
     598          item->class      = class;
     599          item->check_mask = check_mask;
    385600         
    386601          if (NULL == watches->list_of_watches)
    387             watches->list_of_watches = zAVLAllocTree (sh_inotify_getkey, zAVL_KEY_INT);
     602            watches->list_of_watches = zAVLAllocTree (sh_inotify_getkey,
     603                                                      zAVL_KEY_INT);
    388604 
    389605          if (watches->list_of_watches)
    390606            {
    391               *errnum =  zAVLInsert((zAVLTree *)(watches->list_of_watches), item);
     607              *errnum =  zAVLInsert((zAVLTree *)(watches->list_of_watches),
     608                                    item);
     609
    392610              if (*errnum != 0)
    393611                {
     612                  (*errnum == -1) ? *errnum = ENOMEM : EEXIST;
    394613                  sh_inotify_free_watch(item);
    395                   return -1;
     614                  retval = -1;
     615                  goto retpoint;
    396616                }
    397617            }
    398618          else
    399619            {
    400               *errnum = -1;
    401               return -1;
     620              *errnum = ENOMEM;
     621              retval = -1;
     622              goto retpoint;
    402623            }
    403624
     
    405626        }
    406627    }
    407   return 0;
    408 }
     628 retpoint:
     629  SH_MUTEX_UNLOCK(mutex_watches);
     630  return retval;
     631}
     632
     633static void * sh_dummy_sret = NULL;
     634
     635char * sh_inotify_search_item(sh_watches * watches, int watch,
     636                              int * class, unsigned long * check_mask)
     637{
     638  sh_watch * item;
     639  char     * sret = NULL;
     640
     641  /* Take the address to keep gcc from putting it into a register.
     642   * Avoids the 'clobbered by longjmp' warning.
     643   */
     644  sh_dummy_sret = (void *) &sret;
     645
     646  SH_MUTEX_LOCK(mutex_watches);
     647  item = zAVLSearch(watches->list_of_watches, &watch);
     648
     649  if (item)
     650    {
     651      *class      = item->class;
     652      *check_mask = item->check_mask;
     653      sret = sh_util_strdup(item->file);
     654    }
     655  SH_MUTEX_UNLOCK(mutex_watches);
     656  return sret;
     657}
     658
     659static void * sh_dummy_litem = NULL;
    409660
    410661int sh_inotify_wait_for_change(char * filename, sh_watches * watches,
    411662                               int  * errnum, int waitsec)
    412663{
    413   sh_watch   * item;
    414   zAVLTree   * all_watches = (zAVLTree *)(watches->list_of_watches);
     664  sh_watch   * litem;
     665  sh_watch   * zitem;
    415666  int          ifd = sh_inotify_getfd();
    416  
     667
     668  /* Take the address to keep gcc from putting it into a register.
     669   * Avoids the 'clobbered by longjmp' warning.
     670   */
     671  sh_dummy_litem = (void*) &litem;
     672
    417673  *errnum = 0;
    418674
     
    421677  if (ifd >= 0)
    422678    {
     679      volatile ssize_t  i  = 0;
    423680      ssize_t len = -1;
    424       ssize_t  i  = 0;
    425681      int  flag = 0;
    426682      char buffer[1024];
     
    432688      if (filename)
    433689        {
    434           if (sh_inotify_add_watch(filename, watches, errnum) < 0)
     690          if (sh_inotify_add_watch(filename, watches, errnum, 0, 0) < 0)
    435691            {
    436692              retry_msleep(waitsec, 0);
     
    441697      /* -- Check dormant watches for reopening.
    442698       */
    443       for (item = sh_inotify_list_first(&listcursor, watches); item;
    444            item = sh_inotify_list_next(&listcursor, watches))
     699      SH_MUTEX_LOCK(mutex_list_dormant);
     700
     701      for (litem = sh_inotify_list_first(&listcursor, watches); litem;
     702           litem = sh_inotify_list_next(&listcursor, watches))
    445703        {
    446704        have_next:
    447           if (item->file && item->watch == -1)
     705          /* sh_inotify_list_del_cur may return NULL */
     706          if (litem && litem->file && litem->watch == -1)
    448707            {
    449               item->watch = inotify_add_watch (ifd, item->file,
    450                                                IN_MODIFY|IN_DELETE_SELF|IN_MOVE_SELF|IN_UNMOUNT);
    451               if (item->watch >= 0)
     708              litem->watch = inotify_add_watch (ifd, litem->file,
     709                                                SH_INOTIFY_FLAGS);
     710
     711              if (litem->watch >= 0)
    452712                {
    453                   zAVLInsert(all_watches, item);
    454                   item = sh_inotify_list_del_current(&listcursor, watches);
     713                  SH_MUTEX_LOCK(mutex_watches);
     714                  if (watches->list_of_watches)
     715                    zAVLInsert(watches->list_of_watches, litem);
     716                  SH_MUTEX_UNLOCK(mutex_watches);
     717                  litem = sh_inotify_list_del_cur(&listcursor, watches);
    455718                  goto have_next;
    456719                }
    457720            }
    458721        }
     722      SH_MUTEX_UNLOCK(mutex_list_dormant);
    459723
    460724
    461725      /* -- Blocking read on inotify file descriptor
    462726       */
    463       do {
    464         len = read (ifd, &buffer, sizeof(buffer));
    465       } while (len < 0 || errno == EINTR);
     727      sh_inotify_read(buffer, sizeof(buffer));
    466728
    467729      if (len > 0)
     
    475737            event = (struct inotify_event *) &buffer[i];
    476738
    477             item = zAVLSearch(all_watches, &(event->wd));
    478 
    479             if (item)
     739            SH_MUTEX_LOCK(mutex_watches);
     740            zitem = zAVLSearch(watches->list_of_watches, &(event->wd));
     741
     742            if (zitem)
    480743              {
    481744                if (event->mask & IN_MODIFY)
    482745                  {
    483                     item->flag |= SH_INOTIFY_MODIFY;
     746                    zitem->flag |= SH_INOTIFY_MODIFY;
    484747                    flag |= SH_INOTIFY_MODIFY;
    485748                  }
     
    488751                         event->mask & IN_MOVE_SELF   )
    489752                  {
    490                     item->flag |= SH_INOTIFY_REOPEN;
    491                     (void) inotify_rm_watch(ifd, item->watch);
    492                     zAVLDelete(all_watches, item);
    493                     sh_inotify_add_dormant(watches, item);
    494                     item->watch    = -1;
     753                    zitem->flag |= SH_INOTIFY_REOPEN;
     754                    (void) inotify_rm_watch(ifd, zitem->watch);
     755                    zAVLDelete(watches->list_of_watches, zitem);
     756                    sh_inotify_add_dormant(watches, zitem);
     757                    zitem->watch    = -1;
    495758                    flag |= SH_INOTIFY_REOPEN;
    496759                  }
    497760              }
     761            SH_MUTEX_UNLOCK(mutex_watches);
    498762           
    499763            i += sizeof (struct inotify_event) + event->len;
     
    527791}
    528792
     793
    529794/* !defined(HAVE_SYS_INOTIFY_H) */
    530795#else
     
    553818}
    554819
    555 int sh_inotify_add_watch(char * filename, sh_watches * watches, int  * errnum)
     820int sh_inotify_add_watch(char * filename, sh_watches * watches, int  * errnum,
     821                         int class, unsigned long check_mask)
    556822{
    557823  (void) filename;
    558824  (void) watches;
     825  (void) class;
     826  (void) check_mask;
    559827  *errnum = 0;
    560828  return 0;
    561829}
    562830
     831int sh_inotify_add_watch_later(char * filename, sh_watches * watches,
     832                               int  * errnum,
     833                               int class, unsigned long check_mask)
     834{
     835  (void) filename;
     836  (void) watches;
     837  (void) class;
     838  (void) check_mask;
     839  *errnum = 0;
     840  return 0;
     841}
     842
    563843#endif
     844
     845#ifdef SH_CUTEST
     846#include "CuTest.h"
     847void Test_inotify(CuTest *tc) {
     848#if defined(HAVE_SYS_INOTIFY_H) && (defined(SH_WITH_CLIENT) || defined(SH_STANDALONE))
     849
     850  int          ret;
     851  sh_watches   twatch = SH_INOTIFY_INITIALIZER;
     852  sh_watch   * litem;
     853  sh_inotify_listCursor listcursor;
     854  char * p;
     855  int class;
     856  unsigned long check_mask;
     857  int           nrun = 0;
     858
     859  sh_watch aw1 = { -1, 0, 1, 1, "a1" };
     860  sh_watch aw2 = { -1, 0, 2, 1, "a2" };
     861  sh_watch aw3 = {  2, 0, 3, 1, "a3" };
     862  sh_watch aw4 = { -1, 0, 4, 1, "a4" };
     863  sh_watch aw5 = {  5, 0, 5, 1, "a5" };
     864
     865  do {
     866
     867    int          count = 0;
     868
     869    sh_watch * w1 = SH_ALLOC(sizeof(sh_watch));
     870    sh_watch * w2 = SH_ALLOC(sizeof(sh_watch));
     871    sh_watch * w3 = SH_ALLOC(sizeof(sh_watch));
     872    sh_watch * w4 = SH_ALLOC(sizeof(sh_watch));
     873    sh_watch * w5 = SH_ALLOC(sizeof(sh_watch));
     874
     875    memcpy(w1, &aw1, sizeof(sh_watch));
     876    w1->file = sh_util_strdup(aw1.file);
     877    memcpy(w2, &aw2, sizeof(sh_watch));
     878    w2->file = sh_util_strdup(aw2.file);
     879    memcpy(w3, &aw3, sizeof(sh_watch));
     880    w3->file = sh_util_strdup(aw3.file);
     881    memcpy(w4, &aw4, sizeof(sh_watch));
     882    w4->file = sh_util_strdup(aw4.file);
     883    memcpy(w5, &aw5, sizeof(sh_watch));
     884    w5->file = sh_util_strdup(aw5.file);
     885   
     886    ret = sh_inotify_add_dormant(&twatch, w1);
     887    CuAssertIntEquals(tc, ret, 0);
     888    ret = sh_inotify_add_dormant(&twatch, w2);
     889    CuAssertIntEquals(tc, ret, 0);
     890    ret = sh_inotify_add_dormant(&twatch, w3);
     891    CuAssertIntEquals(tc, ret, 0);
     892    ret = sh_inotify_add_dormant(&twatch, w4);
     893    CuAssertIntEquals(tc, ret, 0);
     894    ret = sh_inotify_add_dormant(&twatch, w5);
     895    CuAssertIntEquals(tc, ret, 0);
     896   
     897    /* -- Check dormant watches for reopening.
     898     */
     899    for (litem = sh_inotify_list_first(&listcursor, &twatch); litem;
     900         litem = sh_inotify_list_next(&listcursor, &twatch))
     901      {
     902      have_next:
     903       
     904        /* sh_inotify_list_del_cur may return NULL */
     905        if (litem)
     906          {
     907            ++count;
     908           
     909            if (litem->file && litem->watch == -1)
     910              {
     911               
     912                switch (litem->class)
     913                  {
     914                  case 1:
     915                    CuAssertStrEquals(tc, litem->file, "a1");
     916                    break;
     917                  case 2:
     918                    CuAssertStrEquals(tc, litem->file, "a2");
     919                    break;
     920                  case 3:
     921                    CuAssertStrEquals(tc, litem->file, "deadbeef");
     922                    break;
     923                  case 4:
     924                    CuAssertStrEquals(tc, litem->file, "a4");
     925                    break;
     926                  case 5:
     927                    CuAssertStrEquals(tc, litem->file, "deadbeef");
     928                    break;
     929                  default:
     930                    CuAssertStrEquals(tc, litem->file, "deadbeef");
     931                  }
     932                litem = sh_inotify_list_del_cur(&listcursor, &twatch);
     933                goto have_next;
     934              }
     935            switch (litem->class)
     936              {
     937              case 3:
     938                CuAssertStrEquals(tc, litem->file, "a3");
     939                break;
     940              case 5:
     941                CuAssertStrEquals(tc, litem->file, "a5");
     942                break;
     943              default:
     944                CuAssertStrEquals(tc, litem->file, "foobar");
     945              }     
     946          }
     947      }
     948   
     949    CuAssertIntEquals(tc, count, 5);
     950   
     951    p = sh_inotify_pop_dormant(&twatch, &class, &check_mask);
     952    CuAssertStrEquals(tc, p, "a5");
     953   
     954    p = sh_inotify_pop_dormant(&twatch, &class, &check_mask);
     955    CuAssertStrEquals(tc, p, "a3");
     956    CuAssertIntEquals(tc, class, 3);
     957   
     958    p = sh_inotify_pop_dormant(&twatch, &class, &check_mask);
     959    CuAssertTrue(tc, NULL == p);
     960    CuAssertTrue(tc, NULL == twatch.dormant_watches);
     961
     962    ++nrun;
     963
     964  } while (nrun < 100);
     965
     966#else
     967  (void) tc;
     968#endif
     969
     970  return;
     971}
     972#endif
Note: See TracChangeset for help on using the changeset viewer.