Mirror of :pserver:anonymous@cvs.schmorp.de/schmorpforge libev http://software.schmorp.de/pkg/libev.html
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

3038 lines
64 KiB

14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
13 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
13 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
  1. /*
  2. * libev event processing core, watcher management
  3. *
  4. * Copyright (c) 2007,2008 Marc Alexander Lehmann <libev@schmorp.de>
  5. * All rights reserved.
  6. *
  7. * Redistribution and use in source and binary forms, with or without modifica-
  8. * tion, are permitted provided that the following conditions are met:
  9. *
  10. * 1. Redistributions of source code must retain the above copyright notice,
  11. * this list of conditions and the following disclaimer.
  12. *
  13. * 2. Redistributions in binary form must reproduce the above copyright
  14. * notice, this list of conditions and the following disclaimer in the
  15. * documentation and/or other materials provided with the distribution.
  16. *
  17. * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
  18. * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MER-
  19. * CHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
  20. * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPE-
  21. * CIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  22. * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
  23. * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
  24. * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTH-
  25. * ERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
  26. * OF THE POSSIBILITY OF SUCH DAMAGE.
  27. *
  28. * Alternatively, the contents of this file may be used under the terms of
  29. * the GNU General Public License ("GPL") version 2 or any later version,
  30. * in which case the provisions of the GPL are applicable instead of
  31. * the above. If you wish to allow the use of your version of this file
  32. * only under the terms of the GPL and not to allow others to use your
  33. * version of this file under the BSD license, indicate your decision
  34. * by deleting the provisions above and replace them with the notice
  35. * and other provisions required by the GPL. If you do not delete the
  36. * provisions above, a recipient may use your version of this file under
  37. * either the BSD or the GPL.
  38. */
  39. #ifdef __cplusplus
  40. extern "C" {
  41. #endif
  42. /* this big block deduces configuration from config.h */
  43. #ifndef EV_STANDALONE
  44. # ifdef EV_CONFIG_H
  45. # include EV_CONFIG_H
  46. # else
  47. # include "config.h"
  48. # endif
  49. # if HAVE_CLOCK_GETTIME
  50. # ifndef EV_USE_MONOTONIC
  51. # define EV_USE_MONOTONIC 1
  52. # endif
  53. # ifndef EV_USE_REALTIME
  54. # define EV_USE_REALTIME 1
  55. # endif
  56. # else
  57. # ifndef EV_USE_MONOTONIC
  58. # define EV_USE_MONOTONIC 0
  59. # endif
  60. # ifndef EV_USE_REALTIME
  61. # define EV_USE_REALTIME 0
  62. # endif
  63. # endif
  64. # ifndef EV_USE_NANOSLEEP
  65. # if HAVE_NANOSLEEP
  66. # define EV_USE_NANOSLEEP 1
  67. # else
  68. # define EV_USE_NANOSLEEP 0
  69. # endif
  70. # endif
  71. # ifndef EV_USE_SELECT
  72. # if HAVE_SELECT && HAVE_SYS_SELECT_H
  73. # define EV_USE_SELECT 1
  74. # else
  75. # define EV_USE_SELECT 0
  76. # endif
  77. # endif
  78. # ifndef EV_USE_POLL
  79. # if HAVE_POLL && HAVE_POLL_H
  80. # define EV_USE_POLL 1
  81. # else
  82. # define EV_USE_POLL 0
  83. # endif
  84. # endif
  85. # ifndef EV_USE_EPOLL
  86. # if HAVE_EPOLL_CTL && HAVE_SYS_EPOLL_H
  87. # define EV_USE_EPOLL 1
  88. # else
  89. # define EV_USE_EPOLL 0
  90. # endif
  91. # endif
  92. # ifndef EV_USE_KQUEUE
  93. # if HAVE_KQUEUE && HAVE_SYS_EVENT_H && HAVE_SYS_QUEUE_H
  94. # define EV_USE_KQUEUE 1
  95. # else
  96. # define EV_USE_KQUEUE 0
  97. # endif
  98. # endif
  99. # ifndef EV_USE_PORT
  100. # if HAVE_PORT_H && HAVE_PORT_CREATE
  101. # define EV_USE_PORT 1
  102. # else
  103. # define EV_USE_PORT 0
  104. # endif
  105. # endif
  106. # ifndef EV_USE_INOTIFY
  107. # if HAVE_INOTIFY_INIT && HAVE_SYS_INOTIFY_H
  108. # define EV_USE_INOTIFY 1
  109. # else
  110. # define EV_USE_INOTIFY 0
  111. # endif
  112. # endif
  113. # ifndef EV_USE_EVENTFD
  114. # if HAVE_EVENTFD
  115. # define EV_USE_EVENTFD 1
  116. # else
  117. # define EV_USE_EVENTFD 0
  118. # endif
  119. # endif
  120. #endif
  121. #include <math.h>
  122. #include <stdlib.h>
  123. #include <fcntl.h>
  124. #include <stddef.h>
  125. #include <stdio.h>
  126. #include <assert.h>
  127. #include <errno.h>
  128. #include <sys/types.h>
  129. #include <time.h>
  130. #include <signal.h>
  131. #ifdef EV_H
  132. # include EV_H
  133. #else
  134. # include "ev.h"
  135. #endif
  136. #ifndef _WIN32
  137. # include <sys/time.h>
  138. # include <sys/wait.h>
  139. # include <unistd.h>
  140. #else
  141. # define WIN32_LEAN_AND_MEAN
  142. # include <windows.h>
  143. # ifndef EV_SELECT_IS_WINSOCKET
  144. # define EV_SELECT_IS_WINSOCKET 1
  145. # endif
  146. #endif
  147. /* this block tries to deduce configuration from header-defined symbols and defaults */
  148. #ifndef EV_USE_MONOTONIC
  149. # if defined (_POSIX_MONOTONIC_CLOCK) && _POSIX_MONOTONIC_CLOCK >= 0
  150. # define EV_USE_MONOTONIC 1
  151. # else
  152. # define EV_USE_MONOTONIC 0
  153. # endif
  154. #endif
  155. #ifndef EV_USE_REALTIME
  156. # define EV_USE_REALTIME 0
  157. #endif
  158. #ifndef EV_USE_NANOSLEEP
  159. # if _POSIX_C_SOURCE >= 199309L
  160. # define EV_USE_NANOSLEEP 1
  161. # else
  162. # define EV_USE_NANOSLEEP 0
  163. # endif
  164. #endif
  165. #ifndef EV_USE_SELECT
  166. # define EV_USE_SELECT 1
  167. #endif
  168. #ifndef EV_USE_POLL
  169. # ifdef _WIN32
  170. # define EV_USE_POLL 0
  171. # else
  172. # define EV_USE_POLL 1
  173. # endif
  174. #endif
  175. #ifndef EV_USE_EPOLL
  176. # if __linux && (__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 4))
  177. # define EV_USE_EPOLL 1
  178. # else
  179. # define EV_USE_EPOLL 0
  180. # endif
  181. #endif
  182. #ifndef EV_USE_KQUEUE
  183. # define EV_USE_KQUEUE 0
  184. #endif
  185. #ifndef EV_USE_PORT
  186. # define EV_USE_PORT 0
  187. #endif
  188. #ifndef EV_USE_INOTIFY
  189. # if __linux && (__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 4))
  190. # define EV_USE_INOTIFY 1
  191. # else
  192. # define EV_USE_INOTIFY 0
  193. # endif
  194. #endif
  195. #ifndef EV_PID_HASHSIZE
  196. # if EV_MINIMAL
  197. # define EV_PID_HASHSIZE 1
  198. # else
  199. # define EV_PID_HASHSIZE 16
  200. # endif
  201. #endif
  202. #ifndef EV_INOTIFY_HASHSIZE
  203. # if EV_MINIMAL
  204. # define EV_INOTIFY_HASHSIZE 1
  205. # else
  206. # define EV_INOTIFY_HASHSIZE 16
  207. # endif
  208. #endif
  209. #ifndef EV_USE_EVENTFD
  210. # if __linux && (__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 7))
  211. # define EV_USE_EVENTFD 1
  212. # else
  213. # define EV_USE_EVENTFD 0
  214. # endif
  215. #endif
  216. #if 0 /* debugging */
  217. # define EV_VERIFY 3
  218. # define EV_USE_4HEAP 1
  219. # define EV_HEAP_CACHE_AT 1
  220. #endif
  221. #ifndef EV_VERIFY
  222. # define EV_VERIFY !EV_MINIMAL
  223. #endif
  224. #ifndef EV_USE_4HEAP
  225. # define EV_USE_4HEAP !EV_MINIMAL
  226. #endif
  227. #ifndef EV_HEAP_CACHE_AT
  228. # define EV_HEAP_CACHE_AT !EV_MINIMAL
  229. #endif
  230. /* this block fixes any misconfiguration where we know we run into trouble otherwise */
  231. #ifndef CLOCK_MONOTONIC
  232. # undef EV_USE_MONOTONIC
  233. # define EV_USE_MONOTONIC 0
  234. #endif
  235. #ifndef CLOCK_REALTIME
  236. # undef EV_USE_REALTIME
  237. # define EV_USE_REALTIME 0
  238. #endif
  239. #if !EV_STAT_ENABLE
  240. # undef EV_USE_INOTIFY
  241. # define EV_USE_INOTIFY 0
  242. #endif
  243. #if !EV_USE_NANOSLEEP
  244. # ifndef _WIN32
  245. # include <sys/select.h>
  246. # endif
  247. #endif
  248. #if EV_USE_INOTIFY
  249. # include <sys/inotify.h>
  250. #endif
  251. #if EV_SELECT_IS_WINSOCKET
  252. # include <winsock.h>
  253. #endif
  254. #if EV_USE_EVENTFD
  255. /* our minimum requirement is glibc 2.7 which has the stub, but not the header */
  256. # include <stdint.h>
  257. # ifdef __cplusplus
  258. extern "C" {
  259. # endif
  260. int eventfd (unsigned int initval, int flags);
  261. # ifdef __cplusplus
  262. }
  263. # endif
  264. #endif
  265. /**/
  266. #if EV_VERIFY >= 3
  267. # define EV_FREQUENT_CHECK ev_loop_verify (EV_A)
  268. #else
  269. # define EV_FREQUENT_CHECK do { } while (0)
  270. #endif
  271. /*
  272. * This is used to avoid floating point rounding problems.
  273. * It is added to ev_rt_now when scheduling periodics
  274. * to ensure progress, time-wise, even when rounding
  275. * errors are against us.
  276. * This value is good at least till the year 4000.
  277. * Better solutions welcome.
  278. */
  279. #define TIME_EPSILON 0.0001220703125 /* 1/8192 */
  280. #define MIN_TIMEJUMP 1. /* minimum timejump that gets detected (if monotonic clock available) */
  281. #define MAX_BLOCKTIME 59.743 /* never wait longer than this time (to detect time jumps) */
  282. /*#define CLEANUP_INTERVAL (MAX_BLOCKTIME * 5.) /* how often to try to free memory and re-check fds, TODO */
  283. #if __GNUC__ >= 4
  284. # define expect(expr,value) __builtin_expect ((expr),(value))
  285. # define noinline __attribute__ ((noinline))
  286. #else
  287. # define expect(expr,value) (expr)
  288. # define noinline
  289. # if __STDC_VERSION__ < 199901L && __GNUC__ < 2
  290. # define inline
  291. # endif
  292. #endif
  293. #define expect_false(expr) expect ((expr) != 0, 0)
  294. #define expect_true(expr) expect ((expr) != 0, 1)
  295. #define inline_size static inline
  296. #if EV_MINIMAL
  297. # define inline_speed static noinline
  298. #else
  299. # define inline_speed static inline
  300. #endif
  301. #define NUMPRI (EV_MAXPRI - EV_MINPRI + 1)
  302. #define ABSPRI(w) (((W)w)->priority - EV_MINPRI)
  303. #define EMPTY /* required for microsofts broken pseudo-c compiler */
  304. #define EMPTY2(a,b) /* used to suppress some warnings */
  305. typedef ev_watcher *W;
  306. typedef ev_watcher_list *WL;
  307. typedef ev_watcher_time *WT;
  308. #define ev_active(w) ((W)(w))->active
  309. #define ev_at(w) ((WT)(w))->at
  310. #if EV_USE_MONOTONIC
  311. /* sig_atomic_t is used to avoid per-thread variables or locking but still */
  312. /* giving it a reasonably high chance of working on typical architetcures */
  313. static EV_ATOMIC_T have_monotonic; /* did clock_gettime (CLOCK_MONOTONIC) work? */
  314. #endif
  315. #ifdef _WIN32
  316. # include "ev_win32.c"
  317. #endif
  318. /*****************************************************************************/
  319. static void (*syserr_cb)(const char *msg);
  320. void
  321. ev_set_syserr_cb (void (*cb)(const char *msg))
  322. {
  323. syserr_cb = cb;
  324. }
  325. static void noinline
  326. syserr (const char *msg)
  327. {
  328. if (!msg)
  329. msg = "(libev) system error";
  330. if (syserr_cb)
  331. syserr_cb (msg);
  332. else
  333. {
  334. perror (msg);
  335. abort ();
  336. }
  337. }
  338. static void *
  339. ev_realloc_emul (void *ptr, long size)
  340. {
  341. /* some systems, notably openbsd and darwin, fail to properly
  342. * implement realloc (x, 0) (as required by both ansi c-98 and
  343. * the single unix specification, so work around them here.
  344. */
  345. if (size)
  346. return realloc (ptr, size);
  347. free (ptr);
  348. return 0;
  349. }
  350. static void *(*alloc)(void *ptr, long size) = ev_realloc_emul;
  351. void
  352. ev_set_allocator (void *(*cb)(void *ptr, long size))
  353. {
  354. alloc = cb;
  355. }
  356. inline_speed void *
  357. ev_realloc (void *ptr, long size)
  358. {
  359. ptr = alloc (ptr, size);
  360. if (!ptr && size)
  361. {
  362. fprintf (stderr, "libev: cannot allocate %ld bytes, aborting.", size);
  363. abort ();
  364. }
  365. return ptr;
  366. }
  367. #define ev_malloc(size) ev_realloc (0, (size))
  368. #define ev_free(ptr) ev_realloc ((ptr), 0)
  369. /*****************************************************************************/
  370. typedef struct
  371. {
  372. WL head;
  373. unsigned char events;
  374. unsigned char reify;
  375. #if EV_SELECT_IS_WINSOCKET
  376. SOCKET handle;
  377. #endif
  378. } ANFD;
  379. typedef struct
  380. {
  381. W w;
  382. int events;
  383. } ANPENDING;
  384. #if EV_USE_INOTIFY
  385. /* hash table entry per inotify-id */
  386. typedef struct
  387. {
  388. WL head;
  389. } ANFS;
  390. #endif
  391. /* Heap Entry */
  392. #if EV_HEAP_CACHE_AT
  393. typedef struct {
  394. ev_tstamp at;
  395. WT w;
  396. } ANHE;
  397. #define ANHE_w(he) (he).w /* access watcher, read-write */
  398. #define ANHE_at(he) (he).at /* access cached at, read-only */
  399. #define ANHE_at_cache(he) (he).at = (he).w->at /* update at from watcher */
  400. #else
  401. typedef WT ANHE;
  402. #define ANHE_w(he) (he)
  403. #define ANHE_at(he) (he)->at
  404. #define ANHE_at_cache(he)
  405. #endif
  406. #if EV_MULTIPLICITY
  407. struct ev_loop
  408. {
  409. ev_tstamp ev_rt_now;
  410. #define ev_rt_now ((loop)->ev_rt_now)
  411. #define VAR(name,decl) decl;
  412. #include "ev_vars.h"
  413. #undef VAR
  414. };
  415. #include "ev_wrap.h"
  416. static struct ev_loop default_loop_struct;
  417. struct ev_loop *ev_default_loop_ptr;
  418. #else
  419. ev_tstamp ev_rt_now;
  420. #define VAR(name,decl) static decl;
  421. #include "ev_vars.h"
  422. #undef VAR
  423. static int ev_default_loop_ptr;
  424. #endif
  425. /*****************************************************************************/
  426. ev_tstamp
  427. ev_time (void)
  428. {
  429. #if EV_USE_REALTIME
  430. struct timespec ts;
  431. clock_gettime (CLOCK_REALTIME, &ts);
  432. return ts.tv_sec + ts.tv_nsec * 1e-9;
  433. #else
  434. struct timeval tv;
  435. gettimeofday (&tv, 0);
  436. return tv.tv_sec + tv.tv_usec * 1e-6;
  437. #endif
  438. }
  439. ev_tstamp inline_size
  440. get_clock (void)
  441. {
  442. #if EV_USE_MONOTONIC
  443. if (expect_true (have_monotonic))
  444. {
  445. struct timespec ts;
  446. clock_gettime (CLOCK_MONOTONIC, &ts);
  447. return ts.tv_sec + ts.tv_nsec * 1e-9;
  448. }
  449. #endif
  450. return ev_time ();
  451. }
  452. #if EV_MULTIPLICITY
  453. ev_tstamp
  454. ev_now (EV_P)
  455. {
  456. return ev_rt_now;
  457. }
  458. #endif
  459. void
  460. ev_sleep (ev_tstamp delay)
  461. {
  462. if (