smparkes-eventmachine 0.12.10

Sign up to get free protection for your applications and to get access to all the features.
Files changed (158) hide show
  1. data/.gitignore +15 -0
  2. data/README +81 -0
  3. data/Rakefile +374 -0
  4. data/docs/COPYING +60 -0
  5. data/docs/ChangeLog +211 -0
  6. data/docs/DEFERRABLES +133 -0
  7. data/docs/EPOLL +141 -0
  8. data/docs/GNU +281 -0
  9. data/docs/INSTALL +13 -0
  10. data/docs/KEYBOARD +38 -0
  11. data/docs/LEGAL +25 -0
  12. data/docs/LIGHTWEIGHT_CONCURRENCY +70 -0
  13. data/docs/PURE_RUBY +75 -0
  14. data/docs/RELEASE_NOTES +94 -0
  15. data/docs/SMTP +2 -0
  16. data/docs/SPAWNED_PROCESSES +89 -0
  17. data/docs/TODO +8 -0
  18. data/eventmachine.gemspec +40 -0
  19. data/examples/ex_channel.rb +43 -0
  20. data/examples/ex_queue.rb +2 -0
  21. data/examples/helper.rb +2 -0
  22. data/ext/binder.cpp +125 -0
  23. data/ext/binder.h +46 -0
  24. data/ext/cmain.cpp +827 -0
  25. data/ext/cplusplus.cpp +202 -0
  26. data/ext/ed.cpp +1901 -0
  27. data/ext/ed.h +424 -0
  28. data/ext/em.cpp +2288 -0
  29. data/ext/em.h +229 -0
  30. data/ext/emwin.cpp +300 -0
  31. data/ext/emwin.h +94 -0
  32. data/ext/epoll.cpp +26 -0
  33. data/ext/epoll.h +25 -0
  34. data/ext/eventmachine.h +122 -0
  35. data/ext/eventmachine_cpp.h +96 -0
  36. data/ext/extconf.rb +150 -0
  37. data/ext/fastfilereader/extconf.rb +85 -0
  38. data/ext/fastfilereader/mapper.cpp +214 -0
  39. data/ext/fastfilereader/mapper.h +59 -0
  40. data/ext/fastfilereader/rubymain.cpp +127 -0
  41. data/ext/files.cpp +94 -0
  42. data/ext/files.h +65 -0
  43. data/ext/kb.cpp +81 -0
  44. data/ext/page.cpp +107 -0
  45. data/ext/page.h +51 -0
  46. data/ext/pipe.cpp +349 -0
  47. data/ext/project.h +156 -0
  48. data/ext/rubymain.cpp +1194 -0
  49. data/ext/sigs.cpp +89 -0
  50. data/ext/sigs.h +32 -0
  51. data/ext/ssl.cpp +460 -0
  52. data/ext/ssl.h +94 -0
  53. data/java/.classpath +8 -0
  54. data/java/.project +17 -0
  55. data/java/src/com/rubyeventmachine/EmReactor.java +570 -0
  56. data/java/src/com/rubyeventmachine/EmReactorException.java +40 -0
  57. data/java/src/com/rubyeventmachine/EventableChannel.java +69 -0
  58. data/java/src/com/rubyeventmachine/EventableDatagramChannel.java +189 -0
  59. data/java/src/com/rubyeventmachine/EventableSocketChannel.java +364 -0
  60. data/java/src/com/rubyeventmachine/application/Application.java +194 -0
  61. data/java/src/com/rubyeventmachine/application/Connection.java +74 -0
  62. data/java/src/com/rubyeventmachine/application/ConnectionFactory.java +37 -0
  63. data/java/src/com/rubyeventmachine/application/DefaultConnectionFactory.java +46 -0
  64. data/java/src/com/rubyeventmachine/application/PeriodicTimer.java +38 -0
  65. data/java/src/com/rubyeventmachine/application/Timer.java +54 -0
  66. data/java/src/com/rubyeventmachine/tests/ApplicationTest.java +109 -0
  67. data/java/src/com/rubyeventmachine/tests/ConnectTest.java +148 -0
  68. data/java/src/com/rubyeventmachine/tests/EMTest.java +80 -0
  69. data/java/src/com/rubyeventmachine/tests/TestDatagrams.java +53 -0
  70. data/java/src/com/rubyeventmachine/tests/TestServers.java +75 -0
  71. data/java/src/com/rubyeventmachine/tests/TestTimers.java +90 -0
  72. data/lib/em/buftok.rb +138 -0
  73. data/lib/em/callback.rb +26 -0
  74. data/lib/em/channel.rb +57 -0
  75. data/lib/em/connection.rb +564 -0
  76. data/lib/em/deferrable.rb +192 -0
  77. data/lib/em/file_watch.rb +54 -0
  78. data/lib/em/future.rb +61 -0
  79. data/lib/em/messages.rb +66 -0
  80. data/lib/em/process_watch.rb +44 -0
  81. data/lib/em/processes.rb +119 -0
  82. data/lib/em/protocols/header_and_content.rb +138 -0
  83. data/lib/em/protocols/httpclient.rb +263 -0
  84. data/lib/em/protocols/httpclient2.rb +590 -0
  85. data/lib/em/protocols/line_and_text.rb +125 -0
  86. data/lib/em/protocols/linetext2.rb +161 -0
  87. data/lib/em/protocols/memcache.rb +323 -0
  88. data/lib/em/protocols/object_protocol.rb +45 -0
  89. data/lib/em/protocols/postgres3.rb +247 -0
  90. data/lib/em/protocols/saslauth.rb +175 -0
  91. data/lib/em/protocols/smtpclient.rb +357 -0
  92. data/lib/em/protocols/smtpserver.rb +547 -0
  93. data/lib/em/protocols/socks4.rb +66 -0
  94. data/lib/em/protocols/stomp.rb +200 -0
  95. data/lib/em/protocols/tcptest.rb +53 -0
  96. data/lib/em/protocols.rb +36 -0
  97. data/lib/em/queue.rb +61 -0
  98. data/lib/em/spawnable.rb +85 -0
  99. data/lib/em/streamer.rb +130 -0
  100. data/lib/em/timers.rb +56 -0
  101. data/lib/em/version.rb +3 -0
  102. data/lib/eventmachine.rb +1592 -0
  103. data/lib/evma/callback.rb +32 -0
  104. data/lib/evma/container.rb +75 -0
  105. data/lib/evma/factory.rb +77 -0
  106. data/lib/evma/protocol.rb +87 -0
  107. data/lib/evma/reactor.rb +48 -0
  108. data/lib/evma.rb +32 -0
  109. data/lib/jeventmachine.rb +257 -0
  110. data/lib/pr_eventmachine.rb +1022 -0
  111. data/setup.rb +1585 -0
  112. data/tasks/cpp.rake_example +77 -0
  113. data/tests/client.crt +31 -0
  114. data/tests/client.key +51 -0
  115. data/tests/test_attach.rb +126 -0
  116. data/tests/test_basic.rb +284 -0
  117. data/tests/test_channel.rb +63 -0
  118. data/tests/test_connection_count.rb +35 -0
  119. data/tests/test_defer.rb +47 -0
  120. data/tests/test_epoll.rb +160 -0
  121. data/tests/test_error_handler.rb +35 -0
  122. data/tests/test_errors.rb +82 -0
  123. data/tests/test_exc.rb +55 -0
  124. data/tests/test_file_watch.rb +49 -0
  125. data/tests/test_futures.rb +198 -0
  126. data/tests/test_get_sock_opt.rb +30 -0
  127. data/tests/test_handler_check.rb +37 -0
  128. data/tests/test_hc.rb +218 -0
  129. data/tests/test_httpclient.rb +218 -0
  130. data/tests/test_httpclient2.rb +153 -0
  131. data/tests/test_inactivity_timeout.rb +50 -0
  132. data/tests/test_kb.rb +60 -0
  133. data/tests/test_ltp.rb +182 -0
  134. data/tests/test_ltp2.rb +317 -0
  135. data/tests/test_next_tick.rb +133 -0
  136. data/tests/test_object_protocol.rb +37 -0
  137. data/tests/test_pause.rb +70 -0
  138. data/tests/test_pending_connect_timeout.rb +48 -0
  139. data/tests/test_process_watch.rb +48 -0
  140. data/tests/test_processes.rb +128 -0
  141. data/tests/test_proxy_connection.rb +92 -0
  142. data/tests/test_pure.rb +125 -0
  143. data/tests/test_queue.rb +44 -0
  144. data/tests/test_running.rb +42 -0
  145. data/tests/test_sasl.rb +72 -0
  146. data/tests/test_send_file.rb +242 -0
  147. data/tests/test_servers.rb +76 -0
  148. data/tests/test_smtpclient.rb +83 -0
  149. data/tests/test_smtpserver.rb +85 -0
  150. data/tests/test_spawn.rb +322 -0
  151. data/tests/test_ssl_args.rb +79 -0
  152. data/tests/test_ssl_methods.rb +50 -0
  153. data/tests/test_ssl_verify.rb +82 -0
  154. data/tests/test_timers.rb +162 -0
  155. data/tests/test_ud.rb +36 -0
  156. data/tests/testem.rb +31 -0
  157. data/web/whatis +7 -0
  158. metadata +237 -0
data/ext/pipe.cpp ADDED
@@ -0,0 +1,349 @@
1
+ /*****************************************************************************
2
+
3
+ $Id$
4
+
5
+ File: pipe.cpp
6
+ Date: 30May07
7
+
8
+ Copyright (C) 2006-07 by Francis Cianfrocca. All Rights Reserved.
9
+ Gmail: blackhedd
10
+
11
+ This program is free software; you can redistribute it and/or modify
12
+ it under the terms of either: 1) the GNU General Public License
13
+ as published by the Free Software Foundation; either version 2 of the
14
+ License, or (at your option) any later version; or 2) Ruby's License.
15
+
16
+ See the file COPYING for complete licensing information.
17
+
18
+ *****************************************************************************/
19
+
20
+ #include "project.h"
21
+
22
+
23
+ #ifdef OS_UNIX
24
+ // THIS ENTIRE FILE IS ONLY COMPILED ON UNIX-LIKE SYSTEMS.
25
+
26
+ /******************************
27
+ PipeDescriptor::PipeDescriptor
28
+ ******************************/
29
+
30
+ PipeDescriptor::PipeDescriptor (int fd, pid_t subpid, EventMachine_t *parent_em):
31
+ EventableDescriptor (fd, parent_em),
32
+ bReadAttemptedAfterClose (false),
33
+ LastIo (gCurrentLoopTime),
34
+ InactivityTimeout (0),
35
+ OutboundDataSize (0),
36
+ SubprocessPid (subpid)
37
+ {
38
+ #ifdef HAVE_EPOLL
39
+ EpollEvent.events = EPOLLIN;
40
+ #endif
41
+ #ifdef HAVE_KQUEUE
42
+ MyEventMachine->ArmKqueueReader (this);
43
+ #endif
44
+ }
45
+
46
+
47
+ /*******************************
48
+ PipeDescriptor::~PipeDescriptor
49
+ *******************************/
50
+
51
+ PipeDescriptor::~PipeDescriptor()
52
+ {
53
+ // Run down any stranded outbound data.
54
+ for (size_t i=0; i < OutboundPages.size(); i++)
55
+ OutboundPages[i].Free();
56
+
57
+ /* As a virtual destructor, we come here before the base-class
58
+ * destructor that closes our file-descriptor.
59
+ * We have to make sure the subprocess goes down (if it's not
60
+ * already down) and we have to reap the zombie.
61
+ *
62
+ * This implementation is PROVISIONAL and will surely be improved.
63
+ * The intention here is that we never block, hence the highly
64
+ * undesirable sleeps. But if we can't reap the subprocess even
65
+ * after sending it SIGKILL, then something is wrong and we
66
+ * throw a fatal exception, which is also not something we should
67
+ * be doing.
68
+ *
69
+ * Eventually the right thing to do will be to have the reactor
70
+ * core respond to SIGCHLD by chaining a handler on top of the
71
+ * one Ruby may have installed, and dealing with a list of dead
72
+ * children that are pending cleanup.
73
+ *
74
+ * Since we want to have a signal processor integrated into the
75
+ * client-visible API, let's wait until that is done before cleaning
76
+ * this up.
77
+ *
78
+ * Added a very ugly hack to support passing the subprocess's exit
79
+ * status to the user. It only makes logical sense for user code to access
80
+ * the subprocess exit status in the unbind callback. But unbind is called
81
+ * back during the EventableDescriptor destructor. So by that time there's
82
+ * no way to call back this object through an object binding, because it's
83
+ * already been cleaned up. We might have added a parameter to the unbind
84
+ * callback, but that would probably break a huge amount of existing code.
85
+ * So the hack-solution is to define an instance variable in the EventMachine
86
+ * object and stick the exit status in there, where it can easily be accessed
87
+ * with an accessor visible to user code.
88
+ * User code should ONLY access the exit status from within the unbind callback.
89
+ * Otherwise there's no guarantee it'll be valid.
90
+ * This hack won't make it impossible to run multiple EventMachines in a single
91
+ * process, but it will make it impossible to reliably nest unbind calls
92
+ * within other unbind calls. (Not sure if that's even possible.)
93
+ */
94
+
95
+ assert (MyEventMachine);
96
+
97
+ /* Another hack to make the SubprocessPid available to get_subprocess_status */
98
+ MyEventMachine->SubprocessPid = SubprocessPid;
99
+
100
+ /* 01Mar09: Updated to use a small nanosleep in a loop. When nanosleep is interrupted by SIGCHLD,
101
+ * it resumes the system call after processing the signal (resulting in unnecessary latency).
102
+ * Calling nanosleep in a loop avoids this problem.
103
+ */
104
+ struct timespec req = {0, 50000000}; // 0.05s
105
+ int n;
106
+
107
+ // wait 0.25s for the process to die
108
+ for (n=0; n<5; n++) {
109
+ if (waitpid (SubprocessPid, &(MyEventMachine->SubprocessExitStatus), WNOHANG) != 0) return;
110
+ nanosleep (&req, NULL);
111
+ }
112
+
113
+ // send SIGTERM and wait another 0.5s
114
+ kill (SubprocessPid, SIGTERM);
115
+ for (n=0; n<10; n++) {
116
+ nanosleep (&req, NULL);
117
+ if (waitpid (SubprocessPid, &(MyEventMachine->SubprocessExitStatus), WNOHANG) != 0) return;
118
+ }
119
+
120
+ // send SIGKILL and wait another 1s
121
+ kill (SubprocessPid, SIGKILL);
122
+ for (n=0; n<20; n++) {
123
+ nanosleep (&req, NULL);
124
+ if (waitpid (SubprocessPid, &(MyEventMachine->SubprocessExitStatus), WNOHANG) != 0) return;
125
+ }
126
+
127
+ // still not dead, give up!
128
+ throw std::runtime_error ("unable to reap subprocess");
129
+ }
130
+
131
+
132
+
133
+ /********************
134
+ PipeDescriptor::Read
135
+ ********************/
136
+
137
+ void PipeDescriptor::Read()
138
+ {
139
+ int sd = GetSocket();
140
+ if (sd == INVALID_SOCKET) {
141
+ assert (!bReadAttemptedAfterClose);
142
+ bReadAttemptedAfterClose = true;
143
+ return;
144
+ }
145
+
146
+ LastIo = gCurrentLoopTime;
147
+
148
+ int total_bytes_read = 0;
149
+ char readbuffer [16 * 1024];
150
+
151
+ for (int i=0; i < 10; i++) {
152
+ // Don't read just one buffer and then move on. This is faster
153
+ // if there is a lot of incoming.
154
+ // But don't read indefinitely. Give other sockets a chance to run.
155
+ // NOTICE, we're reading one less than the buffer size.
156
+ // That's so we can put a guard byte at the end of what we send
157
+ // to user code.
158
+ // Use read instead of recv, which on Linux gives a "socket operation
159
+ // on nonsocket" error.
160
+
161
+
162
+ int r = read (sd, readbuffer, sizeof(readbuffer) - 1);
163
+ //cerr << "<R:" << r << ">";
164
+
165
+ if (r > 0) {
166
+ total_bytes_read += r;
167
+
168
+ // Add a null-terminator at the the end of the buffer
169
+ // that we will send to the callback.
170
+ // DO NOT EVER CHANGE THIS. We want to explicitly allow users
171
+ // to be able to depend on this behavior, so they will have
172
+ // the option to do some things faster. Additionally it's
173
+ // a security guard against buffer overflows.
174
+ readbuffer [r] = 0;
175
+ _GenericInboundDispatch(readbuffer, r);
176
+ }
177
+ else if (r == 0) {
178
+ break;
179
+ }
180
+ else {
181
+ // Basically a would-block, meaning we've read everything there is to read.
182
+ break;
183
+ }
184
+
185
+ }
186
+
187
+
188
+ if (total_bytes_read == 0) {
189
+ // If we read no data on a socket that selected readable,
190
+ // it generally means the other end closed the connection gracefully.
191
+ ScheduleClose (false);
192
+ //bCloseNow = true;
193
+ }
194
+
195
+ }
196
+
197
+ /*********************
198
+ PipeDescriptor::Write
199
+ *********************/
200
+
201
+ void PipeDescriptor::Write()
202
+ {
203
+ int sd = GetSocket();
204
+ assert (sd != INVALID_SOCKET);
205
+
206
+ LastIo = gCurrentLoopTime;
207
+ char output_buffer [16 * 1024];
208
+ size_t nbytes = 0;
209
+
210
+ while ((OutboundPages.size() > 0) && (nbytes < sizeof(output_buffer))) {
211
+ OutboundPage *op = &(OutboundPages[0]);
212
+ if ((nbytes + op->Length - op->Offset) < sizeof (output_buffer)) {
213
+ memcpy (output_buffer + nbytes, op->Buffer + op->Offset, op->Length - op->Offset);
214
+ nbytes += (op->Length - op->Offset);
215
+ op->Free();
216
+ OutboundPages.pop_front();
217
+ }
218
+ else {
219
+ int len = sizeof(output_buffer) - nbytes;
220
+ memcpy (output_buffer + nbytes, op->Buffer + op->Offset, len);
221
+ op->Offset += len;
222
+ nbytes += len;
223
+ }
224
+ }
225
+
226
+ // We should never have gotten here if there were no data to write,
227
+ // so assert that as a sanity check.
228
+ // Don't bother to make sure nbytes is less than output_buffer because
229
+ // if it were we probably would have crashed already.
230
+ assert (nbytes > 0);
231
+
232
+ assert (GetSocket() != INVALID_SOCKET);
233
+ int bytes_written = write (GetSocket(), output_buffer, nbytes);
234
+
235
+ if (bytes_written > 0) {
236
+ OutboundDataSize -= bytes_written;
237
+ if ((size_t)bytes_written < nbytes) {
238
+ int len = nbytes - bytes_written;
239
+ char *buffer = (char*) malloc (len + 1);
240
+ if (!buffer)
241
+ throw std::runtime_error ("bad alloc throwing back data");
242
+ memcpy (buffer, output_buffer + bytes_written, len);
243
+ buffer [len] = 0;
244
+ OutboundPages.push_front (OutboundPage (buffer, len));
245
+ }
246
+ #ifdef HAVE_EPOLL
247
+ EpollEvent.events = (EPOLLIN | (SelectForWrite() ? EPOLLOUT : 0));
248
+ assert (MyEventMachine);
249
+ MyEventMachine->Modify (this);
250
+ #endif
251
+ }
252
+ else {
253
+ #ifdef OS_UNIX
254
+ if ((errno != EINPROGRESS) && (errno != EWOULDBLOCK) && (errno != EINTR))
255
+ #endif
256
+ #ifdef OS_WIN32
257
+ if ((errno != WSAEINPROGRESS) && (errno != WSAEWOULDBLOCK))
258
+ #endif
259
+ Close();
260
+ }
261
+ }
262
+
263
+
264
+ /*************************
265
+ PipeDescriptor::Heartbeat
266
+ *************************/
267
+
268
+ void PipeDescriptor::Heartbeat()
269
+ {
270
+ // If an inactivity timeout is defined, then check for it.
271
+ if (InactivityTimeout && ((gCurrentLoopTime - LastIo) >= InactivityTimeout))
272
+ ScheduleClose (false);
273
+ //bCloseNow = true;
274
+ }
275
+
276
+
277
+ /*****************************
278
+ PipeDescriptor::SelectForRead
279
+ *****************************/
280
+
281
+ bool PipeDescriptor::SelectForRead()
282
+ {
283
+ /* Pipe descriptors, being local by definition, don't have
284
+ * a pending state, so this is simpler than for the
285
+ * ConnectionDescriptor object.
286
+ */
287
+ return true;
288
+ }
289
+
290
+ /******************************
291
+ PipeDescriptor::SelectForWrite
292
+ ******************************/
293
+
294
+ bool PipeDescriptor::SelectForWrite()
295
+ {
296
+ /* Pipe descriptors, being local by definition, don't have
297
+ * a pending state, so this is simpler than for the
298
+ * ConnectionDescriptor object.
299
+ */
300
+ return (GetOutboundDataSize() > 0);
301
+ }
302
+
303
+
304
+
305
+
306
+ /********************************
307
+ PipeDescriptor::SendOutboundData
308
+ ********************************/
309
+
310
+ int PipeDescriptor::SendOutboundData (const char *data, int length)
311
+ {
312
+ //if (bCloseNow || bCloseAfterWriting)
313
+ if (IsCloseScheduled())
314
+ return 0;
315
+
316
+ if (!data && (length > 0))
317
+ throw std::runtime_error ("bad outbound data");
318
+ char *buffer = (char *) malloc (length + 1);
319
+ if (!buffer)
320
+ throw std::runtime_error ("no allocation for outbound data");
321
+ memcpy (buffer, data, length);
322
+ buffer [length] = 0;
323
+ OutboundPages.push_back (OutboundPage (buffer, length));
324
+ OutboundDataSize += length;
325
+ #ifdef HAVE_EPOLL
326
+ EpollEvent.events = (EPOLLIN | EPOLLOUT);
327
+ assert (MyEventMachine);
328
+ MyEventMachine->Modify (this);
329
+ #endif
330
+ return length;
331
+ }
332
+
333
+ /********************************
334
+ PipeDescriptor::GetSubprocessPid
335
+ ********************************/
336
+
337
+ bool PipeDescriptor::GetSubprocessPid (pid_t *pid)
338
+ {
339
+ bool ok = false;
340
+ if (pid && (SubprocessPid > 0)) {
341
+ *pid = SubprocessPid;
342
+ ok = true;
343
+ }
344
+ return ok;
345
+ }
346
+
347
+
348
+ #endif // OS_UNIX
349
+
data/ext/project.h ADDED
@@ -0,0 +1,156 @@
1
+ /*****************************************************************************
2
+
3
+ $Id$
4
+
5
+ File: project.h
6
+ Date: 06Apr06
7
+
8
+ Copyright (C) 2006-07 by Francis Cianfrocca. All Rights Reserved.
9
+ Gmail: blackhedd
10
+
11
+ This program is free software; you can redistribute it and/or modify
12
+ it under the terms of either: 1) the GNU General Public License
13
+ as published by the Free Software Foundation; either version 2 of the
14
+ License, or (at your option) any later version; or 2) Ruby's License.
15
+
16
+ See the file COPYING for complete licensing information.
17
+
18
+ *****************************************************************************/
19
+
20
+
21
+ #ifndef __Project__H_
22
+ #define __Project__H_
23
+
24
+
25
+ #ifdef OS_WIN32
26
+ #pragma warning(disable:4786)
27
+ #endif
28
+
29
+ #include <iostream>
30
+ #include <map>
31
+ #include <set>
32
+ #include <vector>
33
+ #include <deque>
34
+ #include <string>
35
+ #include <sstream>
36
+ #include <stdexcept>
37
+
38
+
39
+ #ifdef OS_UNIX
40
+ #include <signal.h>
41
+ #include <netdb.h>
42
+ #include <time.h>
43
+ #include <sys/time.h>
44
+ #include <sys/types.h>
45
+ #include <sys/stat.h>
46
+ #include <sys/socket.h>
47
+ #include <sys/un.h>
48
+ #include <sys/resource.h>
49
+ #include <sys/wait.h>
50
+ #include <assert.h>
51
+ #include <unistd.h>
52
+ #include <fcntl.h>
53
+ #include <errno.h>
54
+ #include <netinet/in.h>
55
+ #include <netinet/tcp.h>
56
+ #include <arpa/inet.h>
57
+ #include <pwd.h>
58
+ typedef int SOCKET;
59
+ #define closesocket close
60
+ #define INVALID_SOCKET -1
61
+ #define SOCKET_ERROR -1
62
+ #ifdef OS_SOLARIS8
63
+ #include <strings.h>
64
+ #include <sys/un.h>
65
+ #ifndef AF_LOCAL
66
+ #define AF_LOCAL AF_UNIX
67
+ #endif
68
+ // INADDR_NONE is undefined on Solaris < 8. Thanks to Brett Eisenberg and Tim Pease.
69
+ #ifndef INADDR_NONE
70
+ #define INADDR_NONE ((unsigned long)-1)
71
+ #endif
72
+ #endif /* OS_SOLARIS8 */
73
+
74
+ #ifdef _AIX
75
+ #include <strings.h>
76
+ #ifndef AF_LOCAL
77
+ #define AF_LOCAL AF_UNIX
78
+ #endif
79
+ #endif /* _AIX */
80
+
81
+ #endif /* OS_UNIX */
82
+
83
+ #ifdef OS_WIN32
84
+ // 21Sep09: windows limits select() to 64 sockets by default, we increase it to 1024 here (before including winsock2.h)
85
+ #define FD_SETSIZE 1024
86
+
87
+ #define WIN32_LEAN_AND_MEAN
88
+ #include <windows.h>
89
+ #include <winsock2.h>
90
+ #include <ws2tcpip.h>
91
+ #include <rpc.h>
92
+ #include <fcntl.h>
93
+ #include <assert.h>
94
+
95
+ typedef int socklen_t;
96
+ typedef int pid_t;
97
+ #endif
98
+
99
+
100
+ using namespace std;
101
+
102
+ #ifdef WITH_SSL
103
+ #include <openssl/ssl.h>
104
+ #include <openssl/err.h>
105
+ #endif
106
+
107
+ #ifdef HAVE_EPOLL
108
+ #include <sys/epoll.h>
109
+ #endif
110
+
111
+ #ifdef HAVE_KQUEUE
112
+ #include <sys/event.h>
113
+ #include <sys/queue.h>
114
+ #endif
115
+
116
+ #ifdef HAVE_INOTIFY
117
+ #include <sys/inotify.h>
118
+ #endif
119
+
120
+ #ifdef HAVE_OLD_INOTIFY
121
+ #include <sys/syscall.h>
122
+ #include <linux/inotify.h>
123
+ static inline int inotify_init (void) { return syscall (__NR_inotify_init); }
124
+ static inline int inotify_add_watch (int fd, const char *name, __u32 mask) { return syscall (__NR_inotify_add_watch, fd, name, mask); }
125
+ static inline int inotify_rm_watch (int fd, __u32 wd) { return syscall (__NR_inotify_rm_watch, fd, wd); }
126
+ #define HAVE_INOTIFY 1
127
+ #endif
128
+
129
+ #ifdef HAVE_INOTIFY
130
+ #define INOTIFY_EVENT_SIZE (sizeof(struct inotify_event))
131
+ #endif
132
+
133
+ #ifdef HAVE_WRITEV
134
+ #include <sys/uio.h>
135
+ #endif
136
+
137
+ #if __cplusplus
138
+ extern "C" {
139
+ #endif
140
+ typedef void (*EMCallback)(const unsigned long, int, const char*, const unsigned long);
141
+ #if __cplusplus
142
+ }
143
+ #endif
144
+
145
+ #include "binder.h"
146
+ #include "em.h"
147
+ #include "epoll.h"
148
+ #include "sigs.h"
149
+ #include "ed.h"
150
+ #include "files.h"
151
+ #include "page.h"
152
+ #include "ssl.h"
153
+ #include "eventmachine.h"
154
+ #include "eventmachine_cpp.h"
155
+
156
+ #endif // __Project__H_