eventmachine 1.0.7-java → 1.0.8-java

Sign up to get free protection for your applications and to get access to all the features.
data/ext/em.cpp CHANGED
@@ -38,6 +38,33 @@ static unsigned int SimultaneousAcceptCount = 10;
38
38
  */
39
39
  static struct sockaddr *name2address (const char *server, int port, int *family, int *bind_size);
40
40
 
41
+ /* Internal helper to create a socket with SOCK_CLOEXEC set, and fall
42
+ * back to fcntl'ing it if the headers/runtime don't support it.
43
+ */
44
+
45
+ int EmSocket (int domain, int type, int protocol)
46
+ {
47
+ int sd;
48
+ #ifdef HAVE_SOCKET_CLOEXEC
49
+ sd = socket (domain, type | SOCK_CLOEXEC, protocol);
50
+ if (sd < 0) {
51
+ sd = socket (domain, type, protocol);
52
+ if (sd < 0) {
53
+ return sd;
54
+ }
55
+ SetFdCloexec(sd);
56
+ }
57
+ #else
58
+ sd = socket (domain, type, protocol);
59
+ if (sd < 0) {
60
+ return sd;
61
+ }
62
+ SetFdCloexec(sd);
63
+ #endif
64
+ return sd;
65
+ }
66
+
67
+
41
68
  /***************************************
42
69
  STATIC EventMachine_t::GetMaxTimerCount
43
70
  ***************************************/
@@ -83,24 +110,29 @@ void EventMachine_t::SetSimultaneousAcceptCount (int count)
83
110
  EventMachine_t::EventMachine_t
84
111
  ******************************/
85
112
 
86
- EventMachine_t::EventMachine_t (EMCallback event_callback):
113
+ EventMachine_t::EventMachine_t (EMCallback event_callback, Poller_t poller):
87
114
  NumCloseScheduled (0),
88
115
  HeartbeatInterval(2000000),
89
116
  EventCallback (event_callback),
90
- NextHeartbeatTime (0),
91
117
  LoopBreakerReader (-1),
92
118
  LoopBreakerWriter (-1),
93
119
  bTerminateSignalReceived (false),
94
- bEpoll (false),
120
+ Poller (poller),
95
121
  epfd (-1),
96
- bKqueue (false),
97
- kqfd (-1),
98
- inotify (NULL)
122
+ kqfd (-1)
123
+ #ifdef HAVE_INOTIFY
124
+ , inotify (NULL)
125
+ #endif
99
126
  {
100
127
  // Default time-slice is just smaller than one hundred mills.
101
128
  Quantum.tv_sec = 0;
102
129
  Quantum.tv_usec = 90000;
103
130
 
131
+ // Override the requested poller back to default if needed.
132
+ #if !defined(HAVE_EPOLL) && !defined(HAVE_KQUEUE)
133
+ Poller = Poller_Default;
134
+ #endif
135
+
104
136
  /* Initialize monotonic timekeeping on OS X before the first call to GetRealTime */
105
137
  #ifdef OS_DARWIN
106
138
  (void) mach_timebase_info(&mach_timebase);
@@ -157,59 +189,25 @@ EventMachine_t::~EventMachine_t()
157
189
  }
158
190
 
159
191
 
160
- /*************************
161
- EventMachine_t::_UseEpoll
162
- *************************/
163
-
164
- void EventMachine_t::_UseEpoll()
165
- {
166
- /* Temporary.
167
- * Use an internal flag to switch in epoll-based functionality until we determine
168
- * how it should be integrated properly and the extent of the required changes.
169
- * A permanent solution needs to allow the integration of additional technologies,
170
- * like kqueue and Solaris's events.
171
- */
172
-
173
- #ifdef HAVE_EPOLL
174
- bEpoll = true;
175
- #endif
176
- }
177
-
178
- /**************************
179
- EventMachine_t::_UseKqueue
180
- **************************/
181
-
182
- void EventMachine_t::_UseKqueue()
183
- {
184
- /* Temporary.
185
- * See comments under _UseEpoll.
186
- */
187
-
188
- #ifdef HAVE_KQUEUE
189
- bKqueue = true;
190
- #endif
191
- }
192
-
193
-
194
192
  /****************************
195
193
  EventMachine_t::ScheduleHalt
196
194
  ****************************/
197
195
 
198
196
  void EventMachine_t::ScheduleHalt()
199
197
  {
200
- /* This is how we stop the machine.
201
- * This can be called by clients. Signal handlers will probably
202
- * set the global flag.
203
- * For now this means there can only be one EventMachine ever running at a time.
204
- *
205
- * IMPORTANT: keep this light, fast, and async-safe. Don't do anything frisky in here,
206
- * because it may be called from signal handlers invoked from code that we don't
207
- * control. At this writing (20Sep06), EM does NOT install any signal handlers of
208
- * its own.
209
- *
210
- * We need a FAQ. And one of the questions is: how do I stop EM when Ctrl-C happens?
211
- * The answer is to call evma_stop_machine, which calls here, from a SIGINT handler.
212
- */
198
+ /* This is how we stop the machine.
199
+ * This can be called by clients. Signal handlers will probably
200
+ * set the global flag.
201
+ * For now this means there can only be one EventMachine ever running at a time.
202
+ *
203
+ * IMPORTANT: keep this light, fast, and async-safe. Don't do anything frisky in here,
204
+ * because it may be called from signal handlers invoked from code that we don't
205
+ * control. At this writing (20Sep06), EM does NOT install any signal handlers of
206
+ * its own.
207
+ *
208
+ * We need a FAQ. And one of the questions is: how do I stop EM when Ctrl-C happens?
209
+ * The answer is to call evma_stop_machine, which calls here, from a SIGINT handler.
210
+ */
213
211
  bTerminateSignalReceived = true;
214
212
 
215
213
  /* Signal the loopbreaker so we break out of long-running select/epoll/kqueue and
@@ -244,33 +242,33 @@ void EventMachine_t::SetTimerQuantum (int interval)
244
242
 
245
243
  void EventMachine_t::SetuidString (const char *username)
246
244
  {
247
- /* This method takes a caller-supplied username and tries to setuid
248
- * to that user. There is no meaningful implementation (and no error)
249
- * on Windows. On Unix, a failure to setuid the caller-supplied string
250
- * causes a fatal abort, because presumably the program is calling here
251
- * in order to fulfill a security requirement. If we fail silently,
252
- * the user may continue to run with too much privilege.
253
- *
254
- * TODO, we need to decide on and document a way of generating C++ level errors
255
- * that can be wrapped in documented Ruby exceptions, so users can catch
256
- * and handle them. And distinguish it from errors that we WON'T let the Ruby
257
- * user catch (like security-violations and resource-overallocation).
258
- * A setuid failure here would be in the latter category.
259
- */
245
+ /* This method takes a caller-supplied username and tries to setuid
246
+ * to that user. There is no meaningful implementation (and no error)
247
+ * on Windows. On Unix, a failure to setuid the caller-supplied string
248
+ * causes a fatal abort, because presumably the program is calling here
249
+ * in order to fulfill a security requirement. If we fail silently,
250
+ * the user may continue to run with too much privilege.
251
+ *
252
+ * TODO, we need to decide on and document a way of generating C++ level errors
253
+ * that can be wrapped in documented Ruby exceptions, so users can catch
254
+ * and handle them. And distinguish it from errors that we WON'T let the Ruby
255
+ * user catch (like security-violations and resource-overallocation).
256
+ * A setuid failure here would be in the latter category.
257
+ */
260
258
 
261
- #ifdef OS_UNIX
262
- if (!username || !*username)
263
- throw std::runtime_error ("setuid_string failed: no username specified");
259
+ #ifdef OS_UNIX
260
+ if (!username || !*username)
261
+ throw std::runtime_error ("setuid_string failed: no username specified");
264
262
 
265
- struct passwd *p = getpwnam (username);
266
- if (!p)
267
- throw std::runtime_error ("setuid_string failed: unknown username");
263
+ struct passwd *p = getpwnam (username);
264
+ if (!p)
265
+ throw std::runtime_error ("setuid_string failed: unknown username");
268
266
 
269
- if (setuid (p->pw_uid) != 0)
270
- throw std::runtime_error ("setuid_string failed: no setuid");
267
+ if (setuid (p->pw_uid) != 0)
268
+ throw std::runtime_error ("setuid_string failed: no setuid");
271
269
 
272
- // Success.
273
- #endif
270
+ // Success.
271
+ #endif
274
272
  }
275
273
 
276
274
 
@@ -309,7 +307,7 @@ EventMachine_t::SignalLoopBreaker
309
307
  void EventMachine_t::SignalLoopBreaker()
310
308
  {
311
309
  #ifdef OS_UNIX
312
- write (LoopBreakerWriter, "", 1);
310
+ (void)write (LoopBreakerWriter, "", 1);
313
311
  #endif
314
312
  #ifdef OS_WIN32
315
313
  sendto (LoopBreakerReader, "", 0, 0, (struct sockaddr*)&(LoopBreakerTarget), sizeof(LoopBreakerTarget));
@@ -333,8 +331,18 @@ void EventMachine_t::_InitializeLoopBreaker()
333
331
 
334
332
  #ifdef OS_UNIX
335
333
  int fd[2];
334
+ #if defined (HAVE_CLOEXEC) && defined (HAVE_PIPE2)
335
+ int pipestatus = pipe2(fd, O_CLOEXEC);
336
+ if (pipestatus < 0) {
337
+ if (pipe(fd))
338
+ throw std::runtime_error (strerror(errno));
339
+ }
340
+ #else
336
341
  if (pipe (fd))
337
342
  throw std::runtime_error (strerror(errno));
343
+ #endif
344
+ if (!SetFdCloexec(fd[0]) || !SetFdCloexec(fd[1]))
345
+ throw std::runtime_error (strerror(errno));
338
346
 
339
347
  LoopBreakerWriter = fd[1];
340
348
  LoopBreakerReader = fd[0];
@@ -345,7 +353,7 @@ void EventMachine_t::_InitializeLoopBreaker()
345
353
  #endif
346
354
 
347
355
  #ifdef OS_WIN32
348
- int sd = socket (AF_INET, SOCK_DGRAM, 0);
356
+ int sd = EmSocket (AF_INET, SOCK_DGRAM, 0);
349
357
  if (sd == INVALID_SOCKET)
350
358
  throw std::runtime_error ("no loop breaker socket");
351
359
  SetSocketNonblocking (sd);
@@ -367,6 +375,43 @@ void EventMachine_t::_InitializeLoopBreaker()
367
375
  throw std::runtime_error ("no loop breaker");
368
376
  LoopBreakerReader = sd;
369
377
  #endif
378
+
379
+ #ifdef HAVE_EPOLL
380
+ if (Poller == Poller_Epoll) {
381
+ epfd = epoll_create (MaxEpollDescriptors);
382
+ if (epfd == -1) {
383
+ char buf[200];
384
+ snprintf (buf, sizeof(buf)-1, "unable to create epoll descriptor: %s", strerror(errno));
385
+ throw std::runtime_error (buf);
386
+ }
387
+ int cloexec = fcntl (epfd, F_GETFD, 0);
388
+ assert (cloexec >= 0);
389
+ cloexec |= FD_CLOEXEC;
390
+ fcntl (epfd, F_SETFD, cloexec);
391
+
392
+ assert (LoopBreakerReader >= 0);
393
+ LoopbreakDescriptor *ld = new LoopbreakDescriptor (LoopBreakerReader, this);
394
+ assert (ld);
395
+ Add (ld);
396
+ }
397
+ #endif
398
+
399
+ #ifdef HAVE_KQUEUE
400
+ if (Poller == Poller_Kqueue) {
401
+ kqfd = kqueue();
402
+ if (kqfd == -1) {
403
+ char buf[200];
404
+ snprintf (buf, sizeof(buf)-1, "unable to create kqueue descriptor: %s", strerror(errno));
405
+ throw std::runtime_error (buf);
406
+ }
407
+ // cloexec not needed. By definition, kqueues are not carried across forks.
408
+
409
+ assert (LoopBreakerReader >= 0);
410
+ LoopbreakDescriptor *ld = new LoopbreakDescriptor (LoopBreakerReader, this);
411
+ assert (ld);
412
+ Add (ld);
413
+ }
414
+ #endif
370
415
  }
371
416
 
372
417
  /***************************
@@ -511,75 +556,44 @@ EventMachine_t::Run
511
556
 
512
557
  void EventMachine_t::Run()
513
558
  {
514
- #ifdef HAVE_EPOLL
515
- if (bEpoll) {
516
- epfd = epoll_create (MaxEpollDescriptors);
517
- if (epfd == -1) {
518
- char buf[200];
519
- snprintf (buf, sizeof(buf)-1, "unable to create epoll descriptor: %s", strerror(errno));
520
- throw std::runtime_error (buf);
521
- }
522
- int cloexec = fcntl (epfd, F_GETFD, 0);
523
- assert (cloexec >= 0);
524
- cloexec |= FD_CLOEXEC;
525
- fcntl (epfd, F_SETFD, cloexec);
526
-
527
- assert (LoopBreakerReader >= 0);
528
- LoopbreakDescriptor *ld = new LoopbreakDescriptor (LoopBreakerReader, this);
529
- assert (ld);
530
- Add (ld);
531
- }
532
- #endif
533
-
534
- #ifdef HAVE_KQUEUE
535
- if (bKqueue) {
536
- kqfd = kqueue();
537
- if (kqfd == -1) {
538
- char buf[200];
539
- snprintf (buf, sizeof(buf)-1, "unable to create kqueue descriptor: %s", strerror(errno));
540
- throw std::runtime_error (buf);
541
- }
542
- // cloexec not needed. By definition, kqueues are not carried across forks.
543
-
544
- assert (LoopBreakerReader >= 0);
545
- LoopbreakDescriptor *ld = new LoopbreakDescriptor (LoopBreakerReader, this);
546
- assert (ld);
547
- Add (ld);
548
- }
549
- #endif
550
-
551
- while (true) {
552
- _UpdateTime();
553
- _RunTimers();
554
-
555
- /* _Add must precede _Modify because the same descriptor might
556
- * be on both lists during the same pass through the machine,
557
- * and to modify a descriptor before adding it would fail.
558
- */
559
- _AddNewDescriptors();
560
- _ModifyDescriptors();
561
-
562
- _RunOnce();
563
- if (bTerminateSignalReceived)
564
- break;
565
- }
559
+ while (RunOnce()) ;
566
560
  }
567
561
 
562
+ /***********************
563
+ EventMachine_t::RunOnce
564
+ ***********************/
568
565
 
569
- /************************
570
- EventMachine_t::_RunOnce
571
- ************************/
572
-
573
- void EventMachine_t::_RunOnce()
566
+ bool EventMachine_t::RunOnce()
574
567
  {
575
- if (bEpoll)
568
+ _UpdateTime();
569
+ _RunTimers();
570
+
571
+ /* _Add must precede _Modify because the same descriptor might
572
+ * be on both lists during the same pass through the machine,
573
+ * and to modify a descriptor before adding it would fail.
574
+ */
575
+ _AddNewDescriptors();
576
+ _ModifyDescriptors();
577
+
578
+ switch (Poller) {
579
+ case Poller_Epoll:
576
580
  _RunEpollOnce();
577
- else if (bKqueue)
581
+ break;
582
+ case Poller_Kqueue:
578
583
  _RunKqueueOnce();
579
- else
584
+ break;
585
+ case Poller_Default:
580
586
  _RunSelectOnce();
587
+ break;
588
+ }
589
+
581
590
  _DispatchHeartbeats();
582
591
  _CleanupSockets();
592
+
593
+ if (bTerminateSignalReceived)
594
+ return false;
595
+
596
+ return true;
583
597
  }
584
598
 
585
599
 
@@ -660,9 +674,9 @@ void EventMachine_t::_RunEpollOnce()
660
674
  EventMachine_t::_RunKqueueOnce
661
675
  ******************************/
662
676
 
677
+ #ifdef HAVE_KQUEUE
663
678
  void EventMachine_t::_RunKqueueOnce()
664
679
  {
665
- #ifdef HAVE_KQUEUE
666
680
  assert (kqfd != -1);
667
681
  int k;
668
682
 
@@ -740,10 +754,13 @@ void EventMachine_t::_RunKqueueOnce()
740
754
  rb_thread_schedule();
741
755
  }
742
756
  #endif
743
- #else
757
+ }
758
+ #else
759
+ void EventMachine_t::_RunKqueueOnce()
760
+ {
744
761
  throw std::runtime_error ("kqueue is not implemented on this platform");
745
- #endif
746
762
  }
763
+ #endif
747
764
 
748
765
 
749
766
  /*********************************
@@ -818,7 +835,7 @@ void EventMachine_t::_CleanupSockets()
818
835
  assert (ed);
819
836
  if (ed->ShouldDelete()) {
820
837
  #ifdef HAVE_EPOLL
821
- if (bEpoll) {
838
+ if (Poller == Poller_Epoll) {
822
839
  assert (epfd != -1);
823
840
  if (ed->GetSocket() != INVALID_SOCKET) {
824
841
  int e = epoll_ctl (epfd, EPOLL_CTL_DEL, ed->GetSocket(), ed->GetEpollEvent());
@@ -845,10 +862,10 @@ void EventMachine_t::_CleanupSockets()
845
862
  EventMachine_t::_ModifyEpollEvent
846
863
  *********************************/
847
864
 
865
+ #ifdef HAVE_EPOLL
848
866
  void EventMachine_t::_ModifyEpollEvent (EventableDescriptor *ed)
849
867
  {
850
- #ifdef HAVE_EPOLL
851
- if (bEpoll) {
868
+ if (Poller == Poller_Epoll) {
852
869
  assert (epfd != -1);
853
870
  assert (ed);
854
871
  assert (ed->GetSocket() != INVALID_SOCKET);
@@ -859,9 +876,10 @@ void EventMachine_t::_ModifyEpollEvent (EventableDescriptor *ed)
859
876
  throw std::runtime_error (buf);
860
877
  }
861
878
  }
862
- #endif
863
879
  }
864
-
880
+ #else
881
+ void EventMachine_t::_ModifyEpollEvent (EventableDescriptor *ed UNUSED) { }
882
+ #endif
865
883
 
866
884
 
867
885
  /**************************
@@ -1082,7 +1100,7 @@ void EventMachine_t::_ReadLoopBreaker()
1082
1100
  * and send a loop-break event back to user code.
1083
1101
  */
1084
1102
  char buffer [1024];
1085
- read (LoopBreakerReader, buffer, sizeof(buffer));
1103
+ (void)read (LoopBreakerReader, buffer, sizeof(buffer));
1086
1104
  if (EventCallback)
1087
1105
  (*EventCallback)(0, EM_LOOPBREAK_SIGNAL, "", 0);
1088
1106
  }
@@ -1118,7 +1136,7 @@ void EventMachine_t::_RunTimers()
1118
1136
  EventMachine_t::InstallOneshotTimer
1119
1137
  ***********************************/
1120
1138
 
1121
- const unsigned long EventMachine_t::InstallOneshotTimer (int milliseconds)
1139
+ const uintptr_t EventMachine_t::InstallOneshotTimer (int milliseconds)
1122
1140
  {
1123
1141
  if (Timers.size() > MaxOutstandingTimers)
1124
1142
  return false;
@@ -1140,7 +1158,7 @@ const unsigned long EventMachine_t::InstallOneshotTimer (int milliseconds)
1140
1158
  EventMachine_t::ConnectToServer
1141
1159
  *******************************/
1142
1160
 
1143
- const unsigned long EventMachine_t::ConnectToServer (const char *bind_addr, int bind_port, const char *server, int port)
1161
+ const uintptr_t EventMachine_t::ConnectToServer (const char *bind_addr, int bind_port, const char *server, int port)
1144
1162
  {
1145
1163
  /* We want to spend no more than a few seconds waiting for a connection
1146
1164
  * to a remote host. So we use a nonblocking connect.
@@ -1174,7 +1192,7 @@ const unsigned long EventMachine_t::ConnectToServer (const char *bind_addr, int
1174
1192
  throw std::runtime_error ("unable to resolve server address");
1175
1193
  bind_as = *bind_as_ptr; // copy because name2address points to a static
1176
1194
 
1177
- int sd = socket (family, SOCK_STREAM, 0);
1195
+ int sd = EmSocket (family, SOCK_STREAM, 0);
1178
1196
  if (sd == INVALID_SOCKET) {
1179
1197
  char buf [200];
1180
1198
  snprintf (buf, sizeof(buf)-1, "unable to create new socket: %s", strerror(errno));
@@ -1206,7 +1224,7 @@ const unsigned long EventMachine_t::ConnectToServer (const char *bind_addr, int
1206
1224
  }
1207
1225
  }
1208
1226
 
1209
- unsigned long out = 0;
1227
+ uintptr_t out = 0;
1210
1228
  int e = 0;
1211
1229
 
1212
1230
  #ifdef OS_UNIX
@@ -1326,7 +1344,7 @@ const unsigned long EventMachine_t::ConnectToServer (const char *bind_addr, int
1326
1344
  EventMachine_t::ConnectToUnixServer
1327
1345
  ***********************************/
1328
1346
 
1329
- const unsigned long EventMachine_t::ConnectToUnixServer (const char *server)
1347
+ const uintptr_t EventMachine_t::ConnectToUnixServer (const char *server)
1330
1348
  {
1331
1349
  /* Connect to a Unix-domain server, which by definition is running
1332
1350
  * on the same host.
@@ -1343,7 +1361,7 @@ const unsigned long EventMachine_t::ConnectToUnixServer (const char *server)
1343
1361
  // The whole rest of this function is only compiled on Unix systems.
1344
1362
  #ifdef OS_UNIX
1345
1363
 
1346
- unsigned long out = 0;
1364
+ uintptr_t out = 0;
1347
1365
 
1348
1366
  if (!server || !*server)
1349
1367
  return 0;
@@ -1360,7 +1378,7 @@ const unsigned long EventMachine_t::ConnectToUnixServer (const char *server)
1360
1378
 
1361
1379
  strcpy (pun.sun_path, server);
1362
1380
 
1363
- int fd = socket (AF_LOCAL, SOCK_STREAM, 0);
1381
+ int fd = EmSocket (AF_LOCAL, SOCK_STREAM, 0);
1364
1382
  if (fd == INVALID_SOCKET)
1365
1383
  return 0;
1366
1384
 
@@ -1399,7 +1417,7 @@ const unsigned long EventMachine_t::ConnectToUnixServer (const char *server)
1399
1417
  EventMachine_t::AttachFD
1400
1418
  ************************/
1401
1419
 
1402
- const unsigned long EventMachine_t::AttachFD (int fd, bool watch_mode)
1420
+ const uintptr_t EventMachine_t::AttachFD (int fd, bool watch_mode)
1403
1421
  {
1404
1422
  #ifdef OS_UNIX
1405
1423
  if (fcntl(fd, F_GETFL, 0) < 0)
@@ -1442,7 +1460,7 @@ const unsigned long EventMachine_t::AttachFD (int fd, bool watch_mode)
1442
1460
 
1443
1461
  Add (cd);
1444
1462
 
1445
- const unsigned long out = cd->GetBinding();
1463
+ const uintptr_t out = cd->GetBinding();
1446
1464
  return out;
1447
1465
  }
1448
1466
 
@@ -1458,7 +1476,7 @@ int EventMachine_t::DetachFD (EventableDescriptor *ed)
1458
1476
  int fd = ed->GetSocket();
1459
1477
 
1460
1478
  #ifdef HAVE_EPOLL
1461
- if (bEpoll) {
1479
+ if (Poller == Poller_Epoll) {
1462
1480
  if (ed->GetSocket() != INVALID_SOCKET) {
1463
1481
  assert (epfd != -1);
1464
1482
  int e = epoll_ctl (epfd, EPOLL_CTL_DEL, ed->GetSocket(), ed->GetEpollEvent());
@@ -1473,7 +1491,7 @@ int EventMachine_t::DetachFD (EventableDescriptor *ed)
1473
1491
  #endif
1474
1492
 
1475
1493
  #ifdef HAVE_KQUEUE
1476
- if (bKqueue) {
1494
+ if (Poller == Poller_Kqueue) {
1477
1495
  // remove any read/write events for this fd
1478
1496
  struct kevent k;
1479
1497
  #ifdef __NetBSD__
@@ -1579,7 +1597,7 @@ struct sockaddr *name2address (const char *server, int port, int *family, int *b
1579
1597
  EventMachine_t::CreateTcpServer
1580
1598
  *******************************/
1581
1599
 
1582
- const unsigned long EventMachine_t::CreateTcpServer (const char *server, int port)
1600
+ const uintptr_t EventMachine_t::CreateTcpServer (const char *server, int port)
1583
1601
  {
1584
1602
  /* Create a TCP-acceptor (server) socket and add it to the event machine.
1585
1603
  * Return the binding of the new acceptor to the caller.
@@ -1595,7 +1613,7 @@ const unsigned long EventMachine_t::CreateTcpServer (const char *server, int por
1595
1613
 
1596
1614
  //struct sockaddr_in sin;
1597
1615
 
1598
- int sd_accept = socket (family, SOCK_STREAM, 0);
1616
+ int sd_accept = EmSocket (family, SOCK_STREAM, 0);
1599
1617
  if (sd_accept == INVALID_SOCKET) {
1600
1618
  goto fail;
1601
1619
  }
@@ -1642,11 +1660,11 @@ const unsigned long EventMachine_t::CreateTcpServer (const char *server, int por
1642
1660
  EventMachine_t::OpenDatagramSocket
1643
1661
  **********************************/
1644
1662
 
1645
- const unsigned long EventMachine_t::OpenDatagramSocket (const char *address, int port)
1663
+ const uintptr_t EventMachine_t::OpenDatagramSocket (const char *address, int port)
1646
1664
  {
1647
- unsigned long output_binding = 0;
1665
+ uintptr_t output_binding = 0;
1648
1666
 
1649
- int sd = socket (AF_INET, SOCK_DGRAM, 0);
1667
+ int sd = EmSocket (AF_INET, SOCK_DGRAM, 0);
1650
1668
  if (sd == INVALID_SOCKET)
1651
1669
  goto fail;
1652
1670
  // from here on, early returns must close the socket!
@@ -1717,10 +1735,10 @@ void EventMachine_t::Add (EventableDescriptor *ed)
1717
1735
  EventMachine_t::ArmKqueueWriter
1718
1736
  *******************************/
1719
1737
 
1738
+ #ifdef HAVE_KQUEUE
1720
1739
  void EventMachine_t::ArmKqueueWriter (EventableDescriptor *ed)
1721
1740
  {
1722
- #ifdef HAVE_KQUEUE
1723
- if (bKqueue) {
1741
+ if (Poller == Poller_Kqueue) {
1724
1742
  if (!ed)
1725
1743
  throw std::runtime_error ("added bad descriptor");
1726
1744
  struct kevent k;
@@ -1736,17 +1754,19 @@ void EventMachine_t::ArmKqueueWriter (EventableDescriptor *ed)
1736
1754
  throw std::runtime_error (buf);
1737
1755
  }
1738
1756
  }
1739
- #endif
1740
1757
  }
1758
+ #else
1759
+ void EventMachine_t::ArmKqueueWriter (EventableDescriptor *ed UNUSED) { }
1760
+ #endif
1741
1761
 
1742
1762
  /*******************************
1743
1763
  EventMachine_t::ArmKqueueReader
1744
1764
  *******************************/
1745
1765
 
1766
+ #ifdef HAVE_KQUEUE
1746
1767
  void EventMachine_t::ArmKqueueReader (EventableDescriptor *ed)
1747
1768
  {
1748
- #ifdef HAVE_KQUEUE
1749
- if (bKqueue) {
1769
+ if (Poller == Poller_Kqueue) {
1750
1770
  if (!ed)
1751
1771
  throw std::runtime_error ("added bad descriptor");
1752
1772
  struct kevent k;
@@ -1762,8 +1782,10 @@ void EventMachine_t::ArmKqueueReader (EventableDescriptor *ed)
1762
1782
  throw std::runtime_error (buf);
1763
1783
  }
1764
1784
  }
1765
- #endif
1766
1785
  }
1786
+ #else
1787
+ void EventMachine_t::ArmKqueueReader (EventableDescriptor *ed UNUSED) { }
1788
+ #endif
1767
1789
 
1768
1790
  /**********************************
1769
1791
  EventMachine_t::_AddNewDescriptors
@@ -1788,7 +1810,7 @@ void EventMachine_t::_AddNewDescriptors()
1788
1810
  throw std::runtime_error ("adding bad descriptor");
1789
1811
 
1790
1812
  #if HAVE_EPOLL
1791
- if (bEpoll) {
1813
+ if (Poller == Poller_Epoll) {
1792
1814
  assert (epfd != -1);
1793
1815
  int e = epoll_ctl (epfd, EPOLL_CTL_ADD, ed->GetSocket(), ed->GetEpollEvent());
1794
1816
  if (e) {
@@ -1801,7 +1823,7 @@ void EventMachine_t::_AddNewDescriptors()
1801
1823
 
1802
1824
  #if HAVE_KQUEUE
1803
1825
  /*
1804
- if (bKqueue) {
1826
+ if (Poller == Poller_Kqueue) {
1805
1827
  // INCOMPLETE. Some descriptors don't want to be readable.
1806
1828
  assert (kqfd != -1);
1807
1829
  struct kevent k;
@@ -1847,7 +1869,7 @@ void EventMachine_t::_ModifyDescriptors()
1847
1869
  */
1848
1870
 
1849
1871
  #ifdef HAVE_EPOLL
1850
- if (bEpoll) {
1872
+ if (Poller == Poller_Epoll) {
1851
1873
  set<EventableDescriptor*>::iterator i = ModifiedDescriptors.begin();
1852
1874
  while (i != ModifiedDescriptors.end()) {
1853
1875
  assert (*i);
@@ -1857,6 +1879,18 @@ void EventMachine_t::_ModifyDescriptors()
1857
1879
  }
1858
1880
  #endif
1859
1881
 
1882
+ #ifdef HAVE_KQUEUE
1883
+ if (Poller == Poller_Kqueue) {
1884
+ set<EventableDescriptor*>::iterator i = ModifiedDescriptors.begin();
1885
+ while (i != ModifiedDescriptors.end()) {
1886
+ assert (*i);
1887
+ if ((*i)->GetKqueueArmWrite())
1888
+ ArmKqueueWriter (*i);
1889
+ ++i;
1890
+ }
1891
+ }
1892
+ #endif
1893
+
1860
1894
  ModifiedDescriptors.clear();
1861
1895
  }
1862
1896
 
@@ -1885,7 +1919,7 @@ void EventMachine_t::Deregister (EventableDescriptor *ed)
1885
1919
  // cut/paste from _CleanupSockets(). The error handling could be
1886
1920
  // refactored out of there, but it is cut/paste all over the
1887
1921
  // file already.
1888
- if (bEpoll) {
1922
+ if (Poller == Poller_Epoll) {
1889
1923
  assert (epfd != -1);
1890
1924
  assert (ed->GetSocket() != INVALID_SOCKET);
1891
1925
  int e = epoll_ctl (epfd, EPOLL_CTL_DEL, ed->GetSocket(), ed->GetEpollEvent());
@@ -1905,7 +1939,7 @@ void EventMachine_t::Deregister (EventableDescriptor *ed)
1905
1939
  EventMachine_t::CreateUnixDomainServer
1906
1940
  **************************************/
1907
1941
 
1908
- const unsigned long EventMachine_t::CreateUnixDomainServer (const char *filename)
1942
+ const uintptr_t EventMachine_t::CreateUnixDomainServer (const char *filename)
1909
1943
  {
1910
1944
  /* Create a UNIX-domain acceptor (server) socket and add it to the event machine.
1911
1945
  * Return the binding of the new acceptor to the caller.
@@ -1923,7 +1957,7 @@ const unsigned long EventMachine_t::CreateUnixDomainServer (const char *filename
1923
1957
 
1924
1958
  struct sockaddr_un s_sun;
1925
1959
 
1926
- int sd_accept = socket (AF_LOCAL, SOCK_STREAM, 0);
1960
+ int sd_accept = EmSocket (AF_LOCAL, SOCK_STREAM, 0);
1927
1961
  if (sd_accept == INVALID_SOCKET) {
1928
1962
  goto fail;
1929
1963
  }
@@ -1971,9 +2005,9 @@ const unsigned long EventMachine_t::CreateUnixDomainServer (const char *filename
1971
2005
  EventMachine_t::AttachSD
1972
2006
  **************************************/
1973
2007
 
1974
- const unsigned long EventMachine_t::AttachSD (int sd_accept)
2008
+ const uintptr_t EventMachine_t::AttachSD (int sd_accept)
1975
2009
  {
1976
- unsigned long output_binding = 0;
2010
+ uintptr_t output_binding = 0;
1977
2011
 
1978
2012
  {
1979
2013
  // Set the acceptor non-blocking.
@@ -2006,7 +2040,7 @@ const unsigned long EventMachine_t::AttachSD (int sd_accept)
2006
2040
  EventMachine_t::Socketpair
2007
2041
  **************************/
2008
2042
 
2009
- const unsigned long EventMachine_t::Socketpair (char * const*cmd_strings)
2043
+ const uintptr_t EventMachine_t::Socketpair (char * const*cmd_strings)
2010
2044
  {
2011
2045
  #ifdef OS_WIN32
2012
2046
  throw std::runtime_error ("socketpair is currently unavailable on this platform");
@@ -2024,7 +2058,7 @@ const unsigned long EventMachine_t::Socketpair (char * const*cmd_strings)
2024
2058
  if ((j==0) || (j==2048))
2025
2059
  return 0;
2026
2060
 
2027
- unsigned long output_binding = 0;
2061
+ uintptr_t output_binding = 0;
2028
2062
 
2029
2063
  int sv[2];
2030
2064
  if (socketpair (AF_LOCAL, SOCK_STREAM, 0, sv) < 0)
@@ -2070,7 +2104,7 @@ const unsigned long EventMachine_t::Socketpair (char * const*cmd_strings)
2070
2104
  EventMachine_t::OpenKeyboard
2071
2105
  ****************************/
2072
2106
 
2073
- const unsigned long EventMachine_t::OpenKeyboard()
2107
+ const uintptr_t EventMachine_t::OpenKeyboard()
2074
2108
  {
2075
2109
  KeyboardDescriptor *kd = new KeyboardDescriptor (this);
2076
2110
  if (!kd)
@@ -2094,10 +2128,10 @@ int EventMachine_t::GetConnectionCount ()
2094
2128
  EventMachine_t::WatchPid
2095
2129
  ************************/
2096
2130
 
2097
- const unsigned long EventMachine_t::WatchPid (int pid)
2131
+ #ifdef HAVE_KQUEUE
2132
+ const uintptr_t EventMachine_t::WatchPid (int pid)
2098
2133
  {
2099
- #ifdef HAVE_KQUEUE
2100
- if (!bKqueue)
2134
+ if (Poller != Poller_Kqueue)
2101
2135
  throw std::runtime_error("must enable kqueue (EM.kqueue=true) for pid watching support");
2102
2136
 
2103
2137
  struct kevent event;
@@ -2112,17 +2146,17 @@ const unsigned long EventMachine_t::WatchPid (int pid)
2112
2146
  sprintf(errbuf, "failed to register file watch descriptor with kqueue: %s", strerror(errno));
2113
2147
  throw std::runtime_error(errbuf);
2114
2148
  }
2115
- #endif
2116
-
2117
- #ifdef HAVE_KQUEUE
2118
2149
  Bindable_t* b = new Bindable_t();
2119
2150
  Pids.insert(make_pair (pid, b));
2120
2151
 
2121
2152
  return b->GetBinding();
2122
- #endif
2123
-
2153
+ }
2154
+ #else
2155
+ const uintptr_t EventMachine_t::WatchPid (int pid UNUSED)
2156
+ {
2124
2157
  throw std::runtime_error("no pid watching support on this system");
2125
2158
  }
2159
+ #endif
2126
2160
 
2127
2161
  /**************************
2128
2162
  EventMachine_t::UnwatchPid
@@ -2148,7 +2182,7 @@ void EventMachine_t::UnwatchPid (int pid)
2148
2182
  delete b;
2149
2183
  }
2150
2184
 
2151
- void EventMachine_t::UnwatchPid (const unsigned long sig)
2185
+ void EventMachine_t::UnwatchPid (const uintptr_t sig)
2152
2186
  {
2153
2187
  for(map<int, Bindable_t*>::iterator i=Pids.begin(); i != Pids.end(); i++)
2154
2188
  {
@@ -2166,7 +2200,7 @@ void EventMachine_t::UnwatchPid (const unsigned long sig)
2166
2200
  EventMachine_t::WatchFile
2167
2201
  *************************/
2168
2202
 
2169
- const unsigned long EventMachine_t::WatchFile (const char *fpath)
2203
+ const uintptr_t EventMachine_t::WatchFile (const char *fpath)
2170
2204
  {
2171
2205
  struct stat sb;
2172
2206
  int sres;
@@ -2197,7 +2231,7 @@ const unsigned long EventMachine_t::WatchFile (const char *fpath)
2197
2231
  #endif
2198
2232
 
2199
2233
  #ifdef HAVE_KQUEUE
2200
- if (!bKqueue)
2234
+ if (Poller != Poller_Kqueue)
2201
2235
  throw std::runtime_error("must enable kqueue (EM.kqueue=true) for file watching support");
2202
2236
 
2203
2237
  // With kqueue we have to open the file first and use the resulting fd to register for events
@@ -2244,7 +2278,7 @@ void EventMachine_t::UnwatchFile (int wd)
2244
2278
  delete b;
2245
2279
  }
2246
2280
 
2247
- void EventMachine_t::UnwatchFile (const unsigned long sig)
2281
+ void EventMachine_t::UnwatchFile (const uintptr_t sig)
2248
2282
  {
2249
2283
  for(map<int, Bindable_t*>::iterator i=Files.begin(); i != Files.end(); i++)
2250
2284
  {
@@ -2270,9 +2304,9 @@ void EventMachine_t::_ReadInotifyEvents()
2270
2304
 
2271
2305
  for (;;) {
2272
2306
  int returned = read(inotify->GetSocket(), buffer, sizeof(buffer));
2273
- assert(!(returned == 0 || returned == -1 && errno == EINVAL));
2307
+ assert(!(returned == 0 || (returned == -1 && errno == EINVAL)));
2274
2308
  if (returned <= 0) {
2275
- break;
2309
+ break;
2276
2310
  }
2277
2311
  int current = 0;
2278
2312
  while (current < returned) {