ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/libev/ev.c
(Generate patch)

Comparing libev/ev.c (file contents):
Revision 1.152 by root, Wed Nov 28 11:15:55 2007 UTC vs.
Revision 1.156 by root, Wed Nov 28 17:50:13 2007 UTC

281 perror (msg); 281 perror (msg);
282 abort (); 282 abort ();
283 } 283 }
284} 284}
285 285
286static void *(*alloc)(void *ptr, size_t size) = realloc; 286static void *(*alloc)(void *ptr, long size);
287 287
288void 288void
289ev_set_allocator (void *(*cb)(void *ptr, size_t size)) 289ev_set_allocator (void *(*cb)(void *ptr, long size))
290{ 290{
291 alloc = cb; 291 alloc = cb;
292} 292}
293 293
294inline_speed void * 294inline_speed void *
295ev_realloc (void *ptr, size_t size) 295ev_realloc (void *ptr, long size)
296{ 296{
297 ptr = alloc (ptr, size); 297 ptr = alloc ? alloc (ptr, size) : realloc (ptr, size);
298 298
299 if (!ptr && size) 299 if (!ptr && size)
300 { 300 {
301 fprintf (stderr, "libev: cannot allocate %ld bytes, aborting.", (long)size); 301 fprintf (stderr, "libev: cannot allocate %ld bytes, aborting.", size);
302 abort (); 302 abort ();
303 } 303 }
304 304
305 return ptr; 305 return ptr;
306} 306}
324{ 324{
325 W w; 325 W w;
326 int events; 326 int events;
327} ANPENDING; 327} ANPENDING;
328 328
329#if EV_USE_INOTIFY
329typedef struct 330typedef struct
330{ 331{
331#if EV_USE_INOTIFY
332 WL head; 332 WL head;
333#endif
334} ANFS; 333} ANFS;
334#endif
335 335
336#if EV_MULTIPLICITY 336#if EV_MULTIPLICITY
337 337
338 struct ev_loop 338 struct ev_loop
339 { 339 {
985 array_free (check, EMPTY0); 985 array_free (check, EMPTY0);
986 986
987 backend = 0; 987 backend = 0;
988} 988}
989 989
990void inline_size infy_fork (EV_P);
991
990void inline_size 992void inline_size
991loop_fork (EV_P) 993loop_fork (EV_P)
992{ 994{
993#if EV_USE_PORT 995#if EV_USE_PORT
994 if (backend == EVBACKEND_PORT ) port_fork (EV_A); 996 if (backend == EVBACKEND_PORT ) port_fork (EV_A);
996#if EV_USE_KQUEUE 998#if EV_USE_KQUEUE
997 if (backend == EVBACKEND_KQUEUE) kqueue_fork (EV_A); 999 if (backend == EVBACKEND_KQUEUE) kqueue_fork (EV_A);
998#endif 1000#endif
999#if EV_USE_EPOLL 1001#if EV_USE_EPOLL
1000 if (backend == EVBACKEND_EPOLL ) epoll_fork (EV_A); 1002 if (backend == EVBACKEND_EPOLL ) epoll_fork (EV_A);
1003#endif
1004#if EV_USE_INOTIFY
1005 infy_fork (EV_A);
1001#endif 1006#endif
1002 1007
1003 if (ev_is_active (&sigev)) 1008 if (ev_is_active (&sigev))
1004 { 1009 {
1005 /* default loop */ 1010 /* default loop */
1716#define MIN_STAT_INTERVAL 0.1074891 1721#define MIN_STAT_INTERVAL 0.1074891
1717 1722
1718void noinline stat_timer_cb (EV_P_ ev_timer *w_, int revents); 1723void noinline stat_timer_cb (EV_P_ ev_timer *w_, int revents);
1719 1724
1720#if EV_USE_INOTIFY 1725#if EV_USE_INOTIFY
1721# define EV_INOTIFY_BUFSIZE ((PATH_MAX + sizeof (struct inotify_event)) + 2048) 1726# define EV_INOTIFY_BUFSIZE 8192
1722 1727
1723static void noinline 1728static void noinline
1724infy_add (EV_P_ ev_stat *w) 1729infy_add (EV_P_ ev_stat *w)
1725{ 1730{
1726 w->wd = inotify_add_watch (fs_fd, w->path, IN_ATTRIB | IN_DELETE_SELF | IN_MOVE_SELF | IN_MODIFY | IN_DONT_FOLLOW | IN_MASK_ADD); 1731 w->wd = inotify_add_watch (fs_fd, w->path, IN_ATTRIB | IN_DELETE_SELF | IN_MOVE_SELF | IN_MODIFY | IN_DONT_FOLLOW | IN_MASK_ADD);
1728 if (w->wd < 0) 1733 if (w->wd < 0)
1729 { 1734 {
1730 ev_timer_start (EV_A_ &w->timer); /* this is not race-free, so we still need to recheck periodically */ 1735 ev_timer_start (EV_A_ &w->timer); /* this is not race-free, so we still need to recheck periodically */
1731 1736
1732 /* monitor some parent directory for speedup hints */ 1737 /* monitor some parent directory for speedup hints */
1733 if (errno == ENOENT || errno == EACCES) 1738 if ((errno == ENOENT || errno == EACCES) && strlen (w->path) < 4096)
1734 { 1739 {
1735 char path [PATH_MAX]; 1740 char path [4096];
1736 strcpy (path, w->path); 1741 strcpy (path, w->path);
1737 1742
1738 do 1743 do
1739 { 1744 {
1740 int mask = IN_MASK_ADD | IN_DELETE_SELF | IN_MOVE_SELF 1745 int mask = IN_MASK_ADD | IN_DELETE_SELF | IN_MOVE_SELF
1744 1749
1745 if (!pend) 1750 if (!pend)
1746 break; /* whoops, no '/', complain to your admin */ 1751 break; /* whoops, no '/', complain to your admin */
1747 1752
1748 *pend = 0; 1753 *pend = 0;
1749 w->wd = inotify_add_watch (fs_fd, path, IN_DELETE_SELF | IN_CREATE | IN_MOVED_TO | IN_MASK_ADD); 1754 w->wd = inotify_add_watch (fs_fd, path, mask);
1750 } 1755 }
1751 while (w->wd < 0 && (errno == ENOENT || errno == EACCES)); 1756 while (w->wd < 0 && (errno == ENOENT || errno == EACCES));
1752 } 1757 }
1753 } 1758 }
1754 else 1759 else
1759} 1764}
1760 1765
1761static void noinline 1766static void noinline
1762infy_del (EV_P_ ev_stat *w) 1767infy_del (EV_P_ ev_stat *w)
1763{ 1768{
1764 WL w_;
1765 int slot; 1769 int slot;
1766 int wd = w->wd; 1770 int wd = w->wd;
1767 1771
1768 if (wd < 0) 1772 if (wd < 0)
1769 return; 1773 return;
1798 { 1802 {
1799 w->wd = -1; 1803 w->wd = -1;
1800 infy_add (EV_A_ w); /* re-add, no matter what */ 1804 infy_add (EV_A_ w); /* re-add, no matter what */
1801 } 1805 }
1802 1806
1803 stat_timer_cb (EV_P_ &w->timer, 0); 1807 stat_timer_cb (EV_A_ &w->timer, 0);
1804 } 1808 }
1805 } 1809 }
1806 } 1810 }
1807} 1811}
1808 1812
1832 ev_set_priority (&fs_w, EV_MAXPRI); 1836 ev_set_priority (&fs_w, EV_MAXPRI);
1833 ev_io_start (EV_A_ &fs_w); 1837 ev_io_start (EV_A_ &fs_w);
1834 } 1838 }
1835} 1839}
1836 1840
1841void inline_size
1842infy_fork (EV_P)
1843{
1844 int slot;
1845
1846 if (fs_fd < 0)
1847 return;
1848
1849 close (fs_fd);
1850 fs_fd = inotify_init ();
1851
1852 for (slot = 0; slot < EV_INOTIFY_HASHSIZE; ++slot)
1853 {
1854 WL w_ = fs_hash [slot].head;
1855 fs_hash [slot].head = 0;
1856
1857 while (w_)
1858 {
1859 ev_stat *w = (ev_stat *)w_;
1860 w_ = w_->next; /* lets us add this watcher */
1861
1862 w->wd = -1;
1863
1864 if (fs_fd >= 0)
1865 infy_add (EV_A_ w); /* re-add, no matter what */
1866 else
1867 ev_timer_start (EV_A_ &w->timer);
1868 }
1869
1870 }
1871}
1872
1837#endif 1873#endif
1838 1874
1839void 1875void
1840ev_stat_stat (EV_P_ ev_stat *w) 1876ev_stat_stat (EV_P_ ev_stat *w)
1841{ 1877{
1853 /* we copy this here each the time so that */ 1889 /* we copy this here each the time so that */
1854 /* prev has the old value when the callback gets invoked */ 1890 /* prev has the old value when the callback gets invoked */
1855 w->prev = w->attr; 1891 w->prev = w->attr;
1856 ev_stat_stat (EV_A_ w); 1892 ev_stat_stat (EV_A_ w);
1857 1893
1858 if (memcmp (&w->prev, &w->attr, sizeof (ev_statdata))) 1894 /* memcmp doesn't work on netbsd, they.... do stuff to their struct stat */
1895 if (
1896 w->prev.st_dev != w->attr.st_dev
1897 || w->prev.st_ino != w->attr.st_ino
1898 || w->prev.st_mode != w->attr.st_mode
1899 || w->prev.st_nlink != w->attr.st_nlink
1900 || w->prev.st_uid != w->attr.st_uid
1901 || w->prev.st_gid != w->attr.st_gid
1902 || w->prev.st_rdev != w->attr.st_rdev
1903 || w->prev.st_size != w->attr.st_size
1904 || w->prev.st_atime != w->attr.st_atime
1905 || w->prev.st_mtime != w->attr.st_mtime
1906 || w->prev.st_ctime != w->attr.st_ctime
1859 { 1907 ) {
1860 #if EV_USE_INOTIFY 1908 #if EV_USE_INOTIFY
1861 infy_del (EV_A_ w); 1909 infy_del (EV_A_ w);
1862 infy_add (EV_A_ w); 1910 infy_add (EV_A_ w);
1863 ev_stat_stat (EV_A_ w); /* avoid race... */ 1911 ev_stat_stat (EV_A_ w); /* avoid race... */
1864 #endif 1912 #endif

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines