eventmachine 1.0.7-java → 1.0.8-java

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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) {