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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +12 -0
- data/README.md +1 -1
- data/ext/binder.cpp +9 -9
- data/ext/binder.h +5 -5
- data/ext/cmain.cpp +68 -55
- data/ext/ed.cpp +106 -70
- data/ext/ed.h +19 -13
- data/ext/em.cpp +228 -194
- data/ext/em.h +33 -28
- data/ext/eventmachine.h +53 -52
- data/ext/extconf.rb +26 -3
- data/ext/fastfilereader/rubymain.cpp +1 -1
- data/ext/kb.cpp +1 -1
- data/ext/pipe.cpp +4 -2
- data/ext/project.h +6 -0
- data/ext/rubymain.cpp +218 -188
- data/ext/ssl.cpp +7 -7
- data/ext/ssl.h +1 -1
- data/lib/em/protocols/line_and_text.rb +1 -0
- data/lib/em/protocols/linetext2.rb +44 -38
- data/lib/em/protocols/smtpclient.rb +60 -31
- data/lib/em/version.rb +1 -1
- data/lib/eventmachine.rb +9 -1
- data/tests/test_ltp2.rb +20 -0
- data/tests/test_smtpclient.rb +20 -0
- metadata +4 -4
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
|
-
|
120
|
+
Poller (poller),
|
95
121
|
epfd (-1),
|
96
|
-
|
97
|
-
|
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
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
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
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
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
|
-
|
262
|
-
|
263
|
-
|
259
|
+
#ifdef OS_UNIX
|
260
|
+
if (!username || !*username)
|
261
|
+
throw std::runtime_error ("setuid_string failed: no username specified");
|
264
262
|
|
265
|
-
|
266
|
-
|
267
|
-
|
263
|
+
struct passwd *p = getpwnam (username);
|
264
|
+
if (!p)
|
265
|
+
throw std::runtime_error ("setuid_string failed: unknown username");
|
268
266
|
|
269
|
-
|
270
|
-
|
267
|
+
if (setuid (p->pw_uid) != 0)
|
268
|
+
throw std::runtime_error ("setuid_string failed: no setuid");
|
271
269
|
|
272
|
-
|
273
|
-
|
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 =
|
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
|
-
|
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
|
-
|
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
|
-
|
581
|
+
break;
|
582
|
+
case Poller_Kqueue:
|
578
583
|
_RunKqueueOnce();
|
579
|
-
|
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
|
-
|
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 (
|
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
|
-
|
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
|
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
|
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 =
|
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
|
-
|
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
|
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
|
-
|
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 =
|
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
|
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
|
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 (
|
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 (
|
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
|
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 =
|
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
|
1663
|
+
const uintptr_t EventMachine_t::OpenDatagramSocket (const char *address, int port)
|
1646
1664
|
{
|
1647
|
-
|
1665
|
+
uintptr_t output_binding = 0;
|
1648
1666
|
|
1649
|
-
int sd =
|
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
|
-
|
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
|
-
|
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 (
|
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 (
|
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 (
|
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 (
|
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
|
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 =
|
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
|
2008
|
+
const uintptr_t EventMachine_t::AttachSD (int sd_accept)
|
1975
2009
|
{
|
1976
|
-
|
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
|
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
|
-
|
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
|
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
|
-
|
2131
|
+
#ifdef HAVE_KQUEUE
|
2132
|
+
const uintptr_t EventMachine_t::WatchPid (int pid)
|
2098
2133
|
{
|
2099
|
-
|
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
|
-
|
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
|
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
|
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 (
|
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
|
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
|
-
|
2309
|
+
break;
|
2276
2310
|
}
|
2277
2311
|
int current = 0;
|
2278
2312
|
while (current < returned) {
|