eventmachine 0.9.0 → 0.10.0
Sign up to get free protection for your applications and to get access to all the features.
- data/DEFERRABLES +3 -3
- data/PURE_RUBY +77 -0
- data/ext/cmain.cpp +41 -2
- data/ext/ed.cpp +67 -3
- data/ext/ed.h +4 -1
- data/ext/em.cpp +33 -10
- data/ext/em.h +6 -14
- data/ext/eventmachine.h +4 -1
- data/ext/pipe.cpp +21 -3
- data/ext/rubymain.cpp +38 -1
- data/ext/ssl.cpp +9 -3
- data/lib/em/streamer.rb +1 -3
- data/lib/eventmachine.rb +190 -38
- data/lib/eventmachine_version.rb +2 -2
- data/lib/pr_eventmachine.rb +309 -28
- data/lib/protocols/httpcli2.rb +784 -0
- data/lib/protocols/saslauth.rb +121 -0
- data/lib/protocols/smtpclient.rb +41 -10
- data/lib/protocols/smtpserver.rb +30 -1
- data/tests/test_basic.rb +33 -2
- data/tests/test_epoll.rb +9 -3
- data/tests/test_errors.rb +72 -0
- data/tests/test_httpclient2.rb +132 -0
- data/tests/test_pure.rb +127 -0
- data/tests/test_timers.rb +30 -1
- metadata +37 -32
- data/ext/eee +0 -173
- data/lib/svn-commit.tmp +0 -4
data/DEFERRABLES
CHANGED
@@ -1,8 +1,8 @@
|
|
1
|
-
$Id: DEFERRABLES
|
1
|
+
$Id: DEFERRABLES 551 2007-09-22 12:57:36Z blackhedd $
|
2
2
|
|
3
3
|
[DOCUMENT UNDER CONSTRUCTION]
|
4
4
|
|
5
|
-
EventMachine (EM) adds two different formalisms for lightweight concurrency to the Ruby programmer's toolbox: spawned processes and deferrables. This note will show you how to use
|
5
|
+
EventMachine (EM) adds two different formalisms for lightweight concurrency to the Ruby programmer's toolbox: spawned processes and deferrables. This note will show you how to use deferrables. For more information, see the separate document LIGHTWEIGHT_CONCURRENCY.
|
6
6
|
|
7
7
|
|
8
8
|
=== What are Deferrables?
|
@@ -132,7 +132,7 @@ Now of course it's somewhat trivial to define two callbacks in the same method,
|
|
132
132
|
|
133
133
|
Remember that you can add a callback or an errback to a Deferrable at any point in time, regardless of whether the status of the deferred operation is known (more precisely, regardless of when #set_deferred_status is called on the object). Even hours or days later.
|
134
134
|
|
135
|
-
When you add a callback or errback to a Deferrable object on which #set_deferred_status has not yet been called, the callback/errback is queued up for future execution, inside the Deferrable object. When you add a callback or errback to a Deferrable on which #set_deferred_status has already been called, the callback/errback will be executed immediately. Your code doesn't have to worry about the ordering, and there are no timing issues, as
|
135
|
+
When you add a callback or errback to a Deferrable object on which #set_deferred_status has not yet been called, the callback/errback is queued up for future execution, inside the Deferrable object. When you add a callback or errback to a Deferrable on which #set_deferred_status has already been called, the callback/errback will be executed immediately. Your code doesn't have to worry about the ordering, and there are no timing issues, as there would be with a threaded approach.
|
136
136
|
|
137
137
|
For more information on Deferrables and their typical usage patterns, look in the EM unit tests. There are also quite a few sugarings (including EM::Deferrable#future) that make typical Deferrable usages syntactically easier to work with.
|
138
138
|
|
data/PURE_RUBY
ADDED
@@ -0,0 +1,77 @@
|
|
1
|
+
$Id: PURE_RUBY 602 2007-12-05 18:45:29Z blackhedd $
|
2
|
+
|
3
|
+
EventMachine is supplied in three alternative versions.
|
4
|
+
|
5
|
+
1) A version that includes a Ruby extension written in C++. This version requires compilation;
|
6
|
+
2) A version for JRuby that contains a precompiled JAR file written in Java;
|
7
|
+
3) A pure Ruby version that has no external dependencies and can run in any Ruby environment.
|
8
|
+
|
9
|
+
The Java version of EventMachine is packaged in a distinct manner and must be installed using a
|
10
|
+
special procedure. This version is described fully in a different document, and not considered
|
11
|
+
further here.
|
12
|
+
|
13
|
+
The C++ and pure-Ruby versions, however, are shipped in the same distribution. You use the same
|
14
|
+
files (either tarball or Ruby gem) to install both of these versions.
|
15
|
+
|
16
|
+
If you intend to use the C++ version, you must successfully compile EventMachine after you install it.
|
17
|
+
(The gem installation attempts to perform this step automatically.)
|
18
|
+
|
19
|
+
If you choose not to compile the EventMachine C++ extension, or if your compilation fails for any
|
20
|
+
reason, you still have a fully-functional installation of the pure-Ruby version of EM.
|
21
|
+
|
22
|
+
However, for technical reasons, a default EM installation (whether or not the compilation succeeds)
|
23
|
+
will always assume that the compiled ("extension") implementation should be used.
|
24
|
+
|
25
|
+
If you want your EM program to use the pure Ruby version, you must specifically request it. There
|
26
|
+
are two ways to do this: by setting either a Ruby global variable, or an environment string.
|
27
|
+
|
28
|
+
The following code will invoke the pure-Ruby implementation of EM:
|
29
|
+
|
30
|
+
$eventmachine_library = :pure_ruby
|
31
|
+
require 'eventmachine'
|
32
|
+
|
33
|
+
EM.library_type #=> "pure_ruby"
|
34
|
+
|
35
|
+
Notice that this requires a code change and is not the preferred way to select pure Ruby, unless
|
36
|
+
for some reason you are absolutely sure you will never want the compiled implementation.
|
37
|
+
|
38
|
+
Setting the following environment string has the same effect:
|
39
|
+
|
40
|
+
export EVENTMACHINE_LIBRARY="pure_ruby"
|
41
|
+
|
42
|
+
This technique gives you the flexibility to select either version at runtime with no code changes.
|
43
|
+
|
44
|
+
Support
|
45
|
+
|
46
|
+
The EventMachine development team has committed to support precisely the same APIs for all the
|
47
|
+
various implementations of EM.
|
48
|
+
|
49
|
+
This means that you can expect any EM program to behave identically, whether you use pure Ruby,
|
50
|
+
the compiled C++ extension, or JRuby. Deviations from this behavior are to be considered bugs
|
51
|
+
and should be reported as such.
|
52
|
+
|
53
|
+
There is a small number of exceptions to this rule, which arise from underlying platform
|
54
|
+
distinctions. Notably, EM#epoll is a silent no-op in the pure Ruby implementation.
|
55
|
+
|
56
|
+
|
57
|
+
When Should You Use the Pure-Ruby Implementation of EM?
|
58
|
+
|
59
|
+
|
60
|
+
Use the pure Ruby implementation of EM when you must support a platform for which no C++ compiler
|
61
|
+
is available, or on which the standard EM C++ code can't be compiled.
|
62
|
+
|
63
|
+
Keep in mind that you don't need a C++ compiler in order to deploy EM applications that rely on
|
64
|
+
the compiled version, so long as appropriate C++ runtime libraries are available on the target platform.
|
65
|
+
|
66
|
+
In extreme cases, you may find that you can develop software with the compiled EM version, but are
|
67
|
+
not allowed to install required runtime libraries on the deployment system(s). This would be another
|
68
|
+
case in which the pure Ruby implementation can be useful.
|
69
|
+
|
70
|
+
In general you should avoid the pure Ruby version of EM when performance and scalability are important.
|
71
|
+
EM in pure Ruby will necessarily run slower than the compiled version. Depending on your application
|
72
|
+
this may or may not be a key issue.
|
73
|
+
|
74
|
+
Also, since EPOLL is not supported in pure Ruby, your applications will be affected by Ruby's built-in
|
75
|
+
limit of 1024 file and socket descriptors that may be open in a single process. For maximum scalability
|
76
|
+
and performance, always use EPOLL if possible.
|
77
|
+
|
data/ext/cmain.cpp
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
/*****************************************************************************
|
2
2
|
|
3
|
-
$Id: cmain.cpp
|
3
|
+
$Id: cmain.cpp 585 2007-11-27 14:29:34Z blackhedd $
|
4
4
|
|
5
5
|
File: cmain.cpp
|
6
6
|
Date: 06Apr06
|
@@ -181,6 +181,17 @@ extern "C" void evma_close_connection (const char *binding, int after_writing)
|
|
181
181
|
ConnectionDescriptor::CloseConnection (binding, (after_writing ? true : false));
|
182
182
|
}
|
183
183
|
|
184
|
+
/***********************************
|
185
|
+
evma_report_connection_error_status
|
186
|
+
***********************************/
|
187
|
+
|
188
|
+
extern "C" int evma_report_connection_error_status (const char *binding)
|
189
|
+
{
|
190
|
+
if (!EventMachine)
|
191
|
+
throw std::runtime_error ("not initialized");
|
192
|
+
return ConnectionDescriptor::ReportErrorStatus (binding);
|
193
|
+
}
|
194
|
+
|
184
195
|
/********************
|
185
196
|
evma_stop_tcp_server
|
186
197
|
********************/
|
@@ -264,6 +275,22 @@ extern "C" int evma_get_subprocess_pid (const char *binding, pid_t *pid)
|
|
264
275
|
return 0;
|
265
276
|
}
|
266
277
|
|
278
|
+
/**************************
|
279
|
+
evma_get_subprocess_status
|
280
|
+
**************************/
|
281
|
+
|
282
|
+
extern "C" int evma_get_subprocess_status (const char *binding, int *status)
|
283
|
+
{
|
284
|
+
if (!EventMachine)
|
285
|
+
throw std::runtime_error ("not initialized");
|
286
|
+
if (status) {
|
287
|
+
*status = EventMachine->SubprocessExitStatus;
|
288
|
+
return 1;
|
289
|
+
}
|
290
|
+
else
|
291
|
+
return 0;
|
292
|
+
}
|
293
|
+
|
267
294
|
|
268
295
|
/*********************
|
269
296
|
evma_signal_loopbreak
|
@@ -331,7 +358,19 @@ extern "C" void evma_set_timer_quantum (int interval)
|
|
331
358
|
{
|
332
359
|
if (!EventMachine)
|
333
360
|
throw std::runtime_error ("not initialized");
|
334
|
-
|
361
|
+
EventMachine->SetTimerQuantum (interval);
|
362
|
+
}
|
363
|
+
|
364
|
+
/************************
|
365
|
+
evma_set_max_timer_count
|
366
|
+
************************/
|
367
|
+
|
368
|
+
extern "C" void evma_set_max_timer_count (int ct)
|
369
|
+
{
|
370
|
+
// This may only be called if the reactor is not running.
|
371
|
+
if (EventMachine)
|
372
|
+
throw std::runtime_error ("already initialized");
|
373
|
+
EventMachine_t::SetMaxTimerCount (ct);
|
335
374
|
}
|
336
375
|
|
337
376
|
/******************
|
data/ext/ed.cpp
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
/*****************************************************************************
|
2
2
|
|
3
|
-
$Id: ed.cpp
|
3
|
+
$Id: ed.cpp 572 2007-11-15 23:13:45Z blackhedd $
|
4
4
|
|
5
5
|
File: ed.cpp
|
6
6
|
Date: 06Apr06
|
@@ -243,6 +243,21 @@ void ConnectionDescriptor::CloseConnection (const char *binding, bool after_writ
|
|
243
243
|
ed->ScheduleClose (after_writing);
|
244
244
|
}
|
245
245
|
|
246
|
+
/***********************************************
|
247
|
+
STATIC: ConnectionDescriptor::ReportErrorStatus
|
248
|
+
***********************************************/
|
249
|
+
|
250
|
+
int ConnectionDescriptor::ReportErrorStatus (const char *binding)
|
251
|
+
{
|
252
|
+
// TODO: This is something of a hack, or at least it's a static method of the wrong class.
|
253
|
+
// TODO: Poor polymorphism here. We should be calling one virtual method
|
254
|
+
// instead of hacking out the runtime information of the target object.
|
255
|
+
ConnectionDescriptor *cd = dynamic_cast <ConnectionDescriptor*> (Bindable_t::GetObject (binding));
|
256
|
+
if (cd)
|
257
|
+
return cd->_ReportErrorStatus();
|
258
|
+
return -1;
|
259
|
+
}
|
260
|
+
|
246
261
|
|
247
262
|
|
248
263
|
/**************************************
|
@@ -395,7 +410,7 @@ void ConnectionDescriptor::Read()
|
|
395
410
|
LastIo = gCurrentLoopTime;
|
396
411
|
|
397
412
|
int total_bytes_read = 0;
|
398
|
-
char readbuffer [16 * 1024];
|
413
|
+
char readbuffer [16 * 1024 + 1];
|
399
414
|
|
400
415
|
for (int i=0; i < 10; i++) {
|
401
416
|
// Don't read just one buffer and then move on. This is faster
|
@@ -612,6 +627,27 @@ void ConnectionDescriptor::_WriteOutboundData()
|
|
612
627
|
}
|
613
628
|
|
614
629
|
|
630
|
+
/****************************************
|
631
|
+
ConnectionDescriptor::_ReportErrorStatus
|
632
|
+
****************************************/
|
633
|
+
|
634
|
+
int ConnectionDescriptor::_ReportErrorStatus()
|
635
|
+
{
|
636
|
+
int error;
|
637
|
+
socklen_t len;
|
638
|
+
len = sizeof(error);
|
639
|
+
#ifdef OS_UNIX
|
640
|
+
int o = getsockopt (GetSocket(), SOL_SOCKET, SO_ERROR, &error, &len);
|
641
|
+
#endif
|
642
|
+
#ifdef OS_WIN32
|
643
|
+
int o = getsockopt (GetSocket(), SOL_SOCKET, SO_ERROR, (char*)&error, &len);
|
644
|
+
#endif
|
645
|
+
if ((o == 0) && (error == 0))
|
646
|
+
return 0;
|
647
|
+
else
|
648
|
+
return 1;
|
649
|
+
}
|
650
|
+
|
615
651
|
|
616
652
|
/******************************
|
617
653
|
ConnectionDescriptor::StartTls
|
@@ -926,6 +962,27 @@ DatagramDescriptor::DatagramDescriptor (int sd, EventMachine_t *parent_em):
|
|
926
962
|
{
|
927
963
|
memset (&ReturnAddress, 0, sizeof(ReturnAddress));
|
928
964
|
|
965
|
+
/* Provisionally added 19Oct07. All datagram sockets support broadcasting.
|
966
|
+
* Until now, sending to a broadcast address would give EACCES (permission denied)
|
967
|
+
* on systems like Linux and BSD that require the SO_BROADCAST socket-option in order
|
968
|
+
* to accept a packet to a broadcast address. Solaris doesn't require it. I think
|
969
|
+
* Windows DOES require it but I'm not sure.
|
970
|
+
*
|
971
|
+
* Ruby does NOT do what we're doing here. In Ruby, you have to explicitly set SO_BROADCAST
|
972
|
+
* on a UDP socket in order to enable broadcasting. The reason for requiring the option
|
973
|
+
* in the first place is so that applications don't send broadcast datagrams by mistake.
|
974
|
+
* I imagine that could happen if a user of an application typed in an address that happened
|
975
|
+
* to be a broadcast address on that particular subnet.
|
976
|
+
*
|
977
|
+
* This is provisional because someone may eventually come up with a good reason not to
|
978
|
+
* do it for all UDP sockets. If that happens, then we'll need to add a usercode-level API
|
979
|
+
* to set the socket option, just like Ruby does. AND WE'LL ALSO BREAK CODE THAT DOESN'T
|
980
|
+
* EXPLICITLY SET THE OPTION.
|
981
|
+
*/
|
982
|
+
|
983
|
+
int oval = 1;
|
984
|
+
int sob = setsockopt (GetSocket(), SOL_SOCKET, SO_BROADCAST, (char*)&oval, sizeof(oval));
|
985
|
+
|
929
986
|
#ifdef HAVE_EPOLL
|
930
987
|
EpollEvent.events = EPOLLIN;
|
931
988
|
#endif
|
@@ -1090,7 +1147,14 @@ DatagramDescriptor::SelectForWrite
|
|
1090
1147
|
|
1091
1148
|
bool DatagramDescriptor::SelectForWrite()
|
1092
1149
|
{
|
1093
|
-
|
1150
|
+
/* Changed 15Nov07, per bug report by Mark Zvillius.
|
1151
|
+
* The outbound data size will be zero if there are zero-length outbound packets,
|
1152
|
+
* so we now select writable in case the outbound page buffer is not empty.
|
1153
|
+
* Note that the superclass ShouldDelete method still checks for outbound data size,
|
1154
|
+
* which may be wrong.
|
1155
|
+
*/
|
1156
|
+
//return (GetOutboundDataSize() > 0); (Original)
|
1157
|
+
return (OutboundPages.size() > 0);
|
1094
1158
|
}
|
1095
1159
|
|
1096
1160
|
|
data/ext/ed.h
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
/*****************************************************************************
|
2
2
|
|
3
|
-
$Id: ed.h
|
3
|
+
$Id: ed.h 585 2007-11-27 14:29:34Z blackhedd $
|
4
4
|
|
5
5
|
File: ed.h
|
6
6
|
Date: 06Apr06
|
@@ -133,6 +133,7 @@ class ConnectionDescriptor: public EventableDescriptor
|
|
133
133
|
|
134
134
|
static int SendDataToConnection (const char*, const char*, int);
|
135
135
|
static void CloseConnection (const char*, bool);
|
136
|
+
static int ReportErrorStatus (const char*);
|
136
137
|
|
137
138
|
int SendOutboundData (const char*, int);
|
138
139
|
|
@@ -157,6 +158,7 @@ class ConnectionDescriptor: public EventableDescriptor
|
|
157
158
|
virtual int GetCommInactivityTimeout (int *value);
|
158
159
|
virtual int SetCommInactivityTimeout (int *value);
|
159
160
|
|
161
|
+
|
160
162
|
protected:
|
161
163
|
struct OutboundPage {
|
162
164
|
OutboundPage (const char *b, int l, int o=0): Buffer(b), Length(l), Offset(o) {}
|
@@ -189,6 +191,7 @@ class ConnectionDescriptor: public EventableDescriptor
|
|
189
191
|
void _DispatchInboundData (const char *buffer, int size);
|
190
192
|
void _DispatchCiphertext();
|
191
193
|
int _SendRawOutboundData (const char*, int);
|
194
|
+
int _ReportErrorStatus();
|
192
195
|
|
193
196
|
};
|
194
197
|
|
data/ext/em.cpp
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
/*****************************************************************************
|
2
2
|
|
3
|
-
$Id: em.cpp
|
3
|
+
$Id: em.cpp 587 2007-12-01 13:50:32Z blackhedd $
|
4
4
|
|
5
5
|
File: em.cpp
|
6
6
|
Date: 06Apr06
|
@@ -34,6 +34,33 @@ unsigned gLastTickCount;
|
|
34
34
|
#endif
|
35
35
|
|
36
36
|
|
37
|
+
/* The numer of max outstanding timers was once a const enum defined in em.h.
|
38
|
+
* Now we define it here so that users can change its value if necessary.
|
39
|
+
*/
|
40
|
+
static int MaxOutstandingTimers = 1000;
|
41
|
+
|
42
|
+
|
43
|
+
|
44
|
+
/***************************************
|
45
|
+
STATIC EventMachine_t::SetMaxTimerCount
|
46
|
+
***************************************/
|
47
|
+
|
48
|
+
void EventMachine_t::SetMaxTimerCount (int count)
|
49
|
+
{
|
50
|
+
/* Allow a user to increase the maximum number of outstanding timers.
|
51
|
+
* If this gets "too high" (a metric that is of course platform dependent),
|
52
|
+
* bad things will happen like performance problems and possible overuse
|
53
|
+
* of memory.
|
54
|
+
* The actual timer mechanism is very efficient so it's hard to know what
|
55
|
+
* the practical max, but 100,000 shouldn't be too problematical.
|
56
|
+
*/
|
57
|
+
if (count < 100)
|
58
|
+
count = 100;
|
59
|
+
MaxOutstandingTimers = count;
|
60
|
+
}
|
61
|
+
|
62
|
+
|
63
|
+
|
37
64
|
/******************************
|
38
65
|
EventMachine_t::EventMachine_t
|
39
66
|
******************************/
|
@@ -1382,8 +1409,11 @@ const char *EventMachine_t::Socketpair (char * const*cmd_strings)
|
|
1382
1409
|
return NULL;
|
1383
1410
|
// from here, all early returns must close the pair of sockets.
|
1384
1411
|
|
1385
|
-
// Set the
|
1386
|
-
|
1412
|
+
// Set the parent side of the socketpair nonblocking.
|
1413
|
+
// We don't care about the child side, and most child processes will expect their
|
1414
|
+
// stdout to be blocking. Thanks to Duane Johnson and Bill Kelly for pointing this out.
|
1415
|
+
// Obviously DON'T set CLOEXEC.
|
1416
|
+
if (!SetSocketNonblocking (sv[0])) {
|
1387
1417
|
close (sv[0]);
|
1388
1418
|
close (sv[1]);
|
1389
1419
|
return NULL;
|
@@ -1420,18 +1450,11 @@ EventMachine_t::OpenKeyboard
|
|
1420
1450
|
|
1421
1451
|
const char *EventMachine_t::OpenKeyboard()
|
1422
1452
|
{
|
1423
|
-
#ifdef OS_UNIX
|
1424
1453
|
KeyboardDescriptor *kd = new KeyboardDescriptor (this);
|
1425
1454
|
if (!kd)
|
1426
1455
|
throw std::runtime_error ("no keyboard-object allocated");
|
1427
1456
|
Add (kd);
|
1428
1457
|
return kd->GetBinding().c_str();
|
1429
|
-
#endif
|
1430
|
-
|
1431
|
-
#ifdef OS_WIN32
|
1432
|
-
throw std::runtime_error ("open-keyboard is currently unavailable on this platform");
|
1433
|
-
return NULL;
|
1434
|
-
#endif
|
1435
1458
|
}
|
1436
1459
|
|
1437
1460
|
|
data/ext/em.h
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
/*****************************************************************************
|
2
2
|
|
3
|
-
$Id: em.h
|
3
|
+
$Id: em.h 585 2007-11-27 14:29:34Z blackhedd $
|
4
4
|
|
5
5
|
File: em.h
|
6
6
|
Date: 06Apr06
|
@@ -56,6 +56,9 @@ class EventMachine_t
|
|
56
56
|
|
57
57
|
class EventMachine_t
|
58
58
|
{
|
59
|
+
public:
|
60
|
+
static void SetMaxTimerCount (int);
|
61
|
+
|
59
62
|
public:
|
60
63
|
EventMachine_t (void(*event_callback)(const char*, int, const char*, int));
|
61
64
|
virtual ~EventMachine_t();
|
@@ -81,21 +84,11 @@ class EventMachine_t
|
|
81
84
|
static void SetuidString (const char*);
|
82
85
|
static int SetRlimitNofile (int);
|
83
86
|
|
87
|
+
int SubprocessExitStatus;
|
88
|
+
|
84
89
|
// Temporary:
|
85
90
|
void _UseEpoll();
|
86
91
|
|
87
|
-
/*
|
88
|
-
public:
|
89
|
-
enum { // Event names
|
90
|
-
TIMER_FIRED = 100,
|
91
|
-
CONNECTION_READ = 101,
|
92
|
-
CONNECTION_UNBOUND = 102,
|
93
|
-
CONNECTION_ACCEPTED = 103,
|
94
|
-
CONNECTION_COMPLETED = 104,
|
95
|
-
LOOPBREAK_SIGNAL = 105
|
96
|
-
};
|
97
|
-
*/
|
98
|
-
|
99
92
|
|
100
93
|
private:
|
101
94
|
bool _RunOnce();
|
@@ -114,7 +107,6 @@ class EventMachine_t
|
|
114
107
|
|
115
108
|
private:
|
116
109
|
enum {
|
117
|
-
MaxOutstandingTimers = 1000,
|
118
110
|
HeartbeatInterval = 2,
|
119
111
|
MaxEpollDescriptors = 64*1024
|
120
112
|
};
|
data/ext/eventmachine.h
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
/*****************************************************************************
|
2
2
|
|
3
|
-
$Id: eventmachine.h
|
3
|
+
$Id: eventmachine.h 584 2007-11-27 07:27:32Z blackhedd $
|
4
4
|
|
5
5
|
File: eventmachine.h
|
6
6
|
Date: 15Apr06
|
@@ -48,6 +48,7 @@ extern "C" {
|
|
48
48
|
void evma_start_tls (const char *binding);
|
49
49
|
int evma_get_peername (const char *binding, struct sockaddr*);
|
50
50
|
int evma_get_subprocess_pid (const char *binding, pid_t*);
|
51
|
+
int evma_get_subprocess_status (const char *binding, int*);
|
51
52
|
int evma_send_data_to_connection (const char *binding, const char *data, int data_length);
|
52
53
|
int evma_send_datagram (const char *binding, const char *data, int data_length, const char *address, int port);
|
53
54
|
int evma_get_comm_inactivity_timeout (const char *binding, /*out*/int *value);
|
@@ -56,8 +57,10 @@ extern "C" {
|
|
56
57
|
int evma_send_file_data_to_connection (const char *binding, const char *filename);
|
57
58
|
|
58
59
|
void evma_close_connection (const char *binding, int after_writing);
|
60
|
+
int evma_report_connection_error_status (const char *binding);
|
59
61
|
void evma_signal_loopbreak();
|
60
62
|
void evma_set_timer_quantum (int);
|
63
|
+
void evma_set_max_timer_count (int);
|
61
64
|
void evma_setuid_string (const char *username);
|
62
65
|
void evma_stop_machine();
|
63
66
|
|