eventmachine-maglev- 0.12.10 → 1.0.0.beta.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (174) hide show
  1. data/.gitignore +7 -0
  2. data/.yardopts +7 -0
  3. data/Gemfile +3 -0
  4. data/README.md +109 -0
  5. data/Rakefile +14 -368
  6. data/docs/DocumentationGuidesIndex.md +27 -0
  7. data/docs/GettingStarted.md +521 -0
  8. data/docs/old/DEFERRABLES +246 -0
  9. data/docs/{KEYBOARD → old/KEYBOARD} +15 -11
  10. data/docs/old/LIGHTWEIGHT_CONCURRENCY +130 -0
  11. data/docs/old/SMTP +4 -0
  12. data/docs/old/SPAWNED_PROCESSES +148 -0
  13. data/eventmachine.gemspec +20 -26
  14. data/examples/guides/getting_started/01_eventmachine_echo_server.rb +18 -0
  15. data/examples/guides/getting_started/02_eventmachine_echo_server_that_recognizes_exit_command.rb +22 -0
  16. data/examples/guides/getting_started/03_simple_chat_server.rb +149 -0
  17. data/examples/guides/getting_started/04_simple_chat_server_step_one.rb +27 -0
  18. data/examples/guides/getting_started/05_simple_chat_server_step_two.rb +43 -0
  19. data/examples/guides/getting_started/06_simple_chat_server_step_three.rb +98 -0
  20. data/examples/guides/getting_started/07_simple_chat_server_step_four.rb +121 -0
  21. data/examples/guides/getting_started/08_simple_chat_server_step_five.rb +141 -0
  22. data/examples/{ex_channel.rb → old/ex_channel.rb} +3 -3
  23. data/examples/old/ex_tick_loop_array.rb +15 -0
  24. data/examples/old/ex_tick_loop_counter.rb +32 -0
  25. data/ext/binder.cpp +0 -1
  26. data/ext/cmain.cpp +40 -29
  27. data/ext/ed.cpp +189 -134
  28. data/ext/ed.h +34 -40
  29. data/ext/em.cpp +388 -340
  30. data/ext/em.h +29 -32
  31. data/ext/eventmachine.h +7 -6
  32. data/ext/extconf.rb +57 -48
  33. data/ext/fastfilereader/extconf.rb +5 -3
  34. data/ext/fastfilereader/mapper.cpp +1 -1
  35. data/ext/fastfilereader/rubymain.cpp +0 -1
  36. data/ext/kb.cpp +1 -3
  37. data/ext/pipe.cpp +9 -11
  38. data/ext/project.h +12 -8
  39. data/ext/rubymain.cpp +158 -112
  40. data/java/src/com/rubyeventmachine/EmReactor.java +3 -2
  41. data/lib/em/buftok.rb +35 -63
  42. data/lib/em/callback.rb +43 -11
  43. data/lib/em/channel.rb +22 -15
  44. data/lib/em/completion.rb +303 -0
  45. data/lib/em/connection.rb +341 -208
  46. data/lib/em/deferrable/pool.rb +2 -0
  47. data/lib/em/deferrable.rb +20 -2
  48. data/lib/em/file_watch.rb +37 -18
  49. data/lib/em/iterator.rb +270 -0
  50. data/lib/em/pool.rb +146 -0
  51. data/lib/em/process_watch.rb +5 -4
  52. data/lib/em/processes.rb +8 -4
  53. data/lib/em/protocols/httpclient.rb +27 -11
  54. data/lib/em/protocols/httpclient2.rb +15 -5
  55. data/lib/em/protocols/line_protocol.rb +29 -0
  56. data/lib/em/protocols/memcache.rb +17 -9
  57. data/lib/em/protocols/object_protocol.rb +2 -1
  58. data/lib/em/protocols/postgres3.rb +2 -1
  59. data/lib/em/protocols/smtpclient.rb +19 -11
  60. data/lib/em/protocols/smtpserver.rb +101 -8
  61. data/lib/em/protocols/stomp.rb +9 -7
  62. data/lib/em/protocols/tcptest.rb +3 -2
  63. data/lib/em/protocols.rb +1 -1
  64. data/lib/{pr_eventmachine.rb → em/pure_ruby.rb} +188 -205
  65. data/lib/em/queue.rb +23 -13
  66. data/lib/em/resolver.rb +192 -0
  67. data/lib/em/spawnable.rb +9 -10
  68. data/lib/em/streamer.rb +34 -46
  69. data/lib/em/threaded_resource.rb +90 -0
  70. data/lib/em/tick_loop.rb +85 -0
  71. data/lib/em/timers.rb +8 -3
  72. data/lib/em/version.rb +1 -1
  73. data/lib/eventmachine.rb +582 -686
  74. data/lib/jeventmachine.rb +25 -3
  75. data/tasks/package.rake +98 -0
  76. data/tasks/test.rake +8 -0
  77. data/tests/em_test_helper.rb +64 -0
  78. data/tests/test_attach.rb +56 -56
  79. data/tests/test_basic.rb +111 -168
  80. data/tests/test_channel.rb +5 -6
  81. data/tests/test_completion.rb +177 -0
  82. data/tests/test_connection_count.rb +1 -3
  83. data/tests/test_defer.rb +3 -32
  84. data/tests/test_deferrable.rb +35 -0
  85. data/tests/test_epoll.rb +27 -57
  86. data/tests/test_error_handler.rb +10 -7
  87. data/tests/test_exc.rb +6 -33
  88. data/tests/test_file_watch.rb +51 -35
  89. data/tests/test_futures.rb +10 -38
  90. data/tests/test_get_sock_opt.rb +27 -20
  91. data/tests/test_handler_check.rb +1 -3
  92. data/tests/test_hc.rb +49 -112
  93. data/tests/test_httpclient.rb +34 -62
  94. data/tests/test_httpclient2.rb +14 -39
  95. data/tests/test_inactivity_timeout.rb +44 -40
  96. data/tests/test_kb.rb +26 -52
  97. data/tests/test_ltp.rb +27 -71
  98. data/tests/test_ltp2.rb +1 -30
  99. data/tests/test_next_tick.rb +2 -31
  100. data/tests/test_object_protocol.rb +8 -9
  101. data/tests/test_pause.rb +45 -37
  102. data/tests/test_pending_connect_timeout.rb +42 -38
  103. data/tests/test_pool.rb +128 -0
  104. data/tests/test_process_watch.rb +37 -37
  105. data/tests/test_processes.rb +92 -110
  106. data/tests/test_proxy_connection.rb +137 -61
  107. data/tests/test_pure.rb +30 -67
  108. data/tests/test_queue.rb +10 -4
  109. data/tests/test_resolver.rb +55 -0
  110. data/tests/test_running.rb +1 -29
  111. data/tests/test_sasl.rb +8 -33
  112. data/tests/test_send_file.rb +163 -188
  113. data/tests/test_servers.rb +12 -55
  114. data/tests/test_shutdown_hooks.rb +23 -0
  115. data/tests/test_smtpclient.rb +1 -29
  116. data/tests/test_smtpserver.rb +1 -29
  117. data/tests/test_spawn.rb +2 -31
  118. data/tests/test_ssl_args.rb +9 -10
  119. data/tests/test_ssl_methods.rb +1 -3
  120. data/tests/test_ssl_verify.rb +63 -63
  121. data/tests/test_threaded_resource.rb +53 -0
  122. data/tests/test_tick_loop.rb +59 -0
  123. data/tests/test_timers.rb +52 -91
  124. data/tests/test_ud.rb +1 -29
  125. data/tests/test_unbind_reason.rb +31 -0
  126. metadata +113 -70
  127. data/README +0 -82
  128. data/docs/DEFERRABLES +0 -133
  129. data/docs/LIGHTWEIGHT_CONCURRENCY +0 -70
  130. data/docs/SMTP +0 -2
  131. data/docs/SPAWNED_PROCESSES +0 -89
  132. data/ext/cplusplus.cpp +0 -202
  133. data/ext/emwin.cpp +0 -300
  134. data/ext/emwin.h +0 -94
  135. data/ext/epoll.cpp +0 -26
  136. data/ext/epoll.h +0 -25
  137. data/ext/eventmachine_cpp.h +0 -96
  138. data/ext/files.cpp +0 -94
  139. data/ext/files.h +0 -65
  140. data/ext/sigs.cpp +0 -89
  141. data/ext/sigs.h +0 -32
  142. data/java/src/com/rubyeventmachine/application/Application.java +0 -194
  143. data/java/src/com/rubyeventmachine/application/Connection.java +0 -74
  144. data/java/src/com/rubyeventmachine/application/ConnectionFactory.java +0 -37
  145. data/java/src/com/rubyeventmachine/application/DefaultConnectionFactory.java +0 -46
  146. data/java/src/com/rubyeventmachine/application/PeriodicTimer.java +0 -38
  147. data/java/src/com/rubyeventmachine/application/Timer.java +0 -54
  148. data/java/src/com/rubyeventmachine/tests/ApplicationTest.java +0 -109
  149. data/java/src/com/rubyeventmachine/tests/ConnectTest.java +0 -148
  150. data/java/src/com/rubyeventmachine/tests/EMTest.java +0 -80
  151. data/java/src/com/rubyeventmachine/tests/TestDatagrams.java +0 -53
  152. data/java/src/com/rubyeventmachine/tests/TestServers.java +0 -75
  153. data/java/src/com/rubyeventmachine/tests/TestTimers.java +0 -90
  154. data/lib/evma/callback.rb +0 -32
  155. data/lib/evma/container.rb +0 -75
  156. data/lib/evma/factory.rb +0 -77
  157. data/lib/evma/protocol.rb +0 -87
  158. data/lib/evma/reactor.rb +0 -48
  159. data/lib/evma.rb +0 -32
  160. data/setup.rb +0 -1585
  161. data/tests/test_errors.rb +0 -82
  162. data/tests/testem.rb +0 -31
  163. data/web/whatis +0 -7
  164. /data/{docs/GNU → GNU} +0 -0
  165. /data/{docs/COPYING → LICENSE} +0 -0
  166. /data/docs/{ChangeLog → old/ChangeLog} +0 -0
  167. /data/docs/{EPOLL → old/EPOLL} +0 -0
  168. /data/docs/{INSTALL → old/INSTALL} +0 -0
  169. /data/docs/{LEGAL → old/LEGAL} +0 -0
  170. /data/docs/{PURE_RUBY → old/PURE_RUBY} +0 -0
  171. /data/docs/{RELEASE_NOTES → old/RELEASE_NOTES} +0 -0
  172. /data/docs/{TODO → old/TODO} +0 -0
  173. /data/examples/{ex_queue.rb → old/ex_queue.rb} +0 -0
  174. /data/examples/{helper.rb → old/helper.rb} +0 -0
@@ -1,89 +0,0 @@
1
- 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 spawned processes. For more information, see the separate document LIGHTWEIGHT_CONCURRENCY.
2
-
3
-
4
- === What are Spawned Processes?
5
-
6
- Spawned Processes in EventMachine are inspired directly by the "processes" found in the Erlang programming language. EM deliberately borrows much (but not all) of Erlang's terminology. However, EM's spawned processes differ from Erlang's in ways that reflect not only Ruby style, but also the fact that Ruby is not a functional language like Erlang.
7
-
8
- Let's proceed with a complete, working code sample that we will analyze line by line. Here's an EM implementation of the "ping-pong" program that also appears in the Erlang tutorial:
9
-
10
-
11
- require 'eventmachine'
12
-
13
- EM.run {
14
- pong = EM.spawn {|x, ping|
15
- puts "Pong received #{x}"
16
- ping.notify( x-1 )
17
- }
18
-
19
- ping = EM.spawn {|x|
20
- if x > 0
21
- puts "Pinging #{x}"
22
- pong.notify x, self
23
- else
24
- EM.stop
25
- end
26
- }
27
-
28
- ping.notify 3
29
- }
30
-
31
- If you run this program, you'll see the following output:
32
-
33
- Pinging 3
34
- Pong received 3
35
- Pinging 2
36
- Pong received 2
37
- Pinging 1
38
- Pong received 1
39
-
40
- Let's take it step by step.
41
-
42
- EventMachine#spawn works very much like the built-in function spawn in Erlang. It returns a reference to a Ruby object of class EventMachine::SpawnedProcess, which is actually a schedulable entity. In Erlang, the value returned from spawn is called a "process identifier" or "pid." But we'll refer to the Ruby object returned from EM#spawn simply as a "spawned process."
43
-
44
- You pass a Ruby block with zero or more parameters to EventMachine#spawn. Like all Ruby blocks, this one is a closure, so it can refer to variables defined in the local context when you call EM#spawn.
45
-
46
- However, the code block passed to EM#spawn does NOT execute immediately by default. Rather, it will execute only when the Spawned Object is "notified." In Erlang, this process is called "message passing," and is done with the operator !, but in Ruby it's done simply by calling the #notify method of a spawned-process object. The parameters you pass to #notify must match those defined in the block that was originally passed to EM#spawn.
47
-
48
- When you call the #notify method of a spawned-process object, EM's reactor core will execute the code block originally passed to EM#spawn, at some point in the future. (#notify itself merely adds a notification to the object's message queue and ALWAYS returns immediately.)
49
-
50
- When a SpawnedProcess object executes a notification, it does so in the context of the SpawnedProcess object itself. The notified code block can see local context from the point at which EM#spawn was called. However, the value of "self" inside the notified code block is a reference to the SpawnedProcesss object itself.
51
-
52
- An EM spawned process is nothing more than a Ruby object with a message queue attached to it. You can have any number of spawned processes in your program without compromising scalability. You can notify a spawned process any number of times, and each notification will cause a "message" to be placed in the queue of the spawned process. Spawned processes with non-empty message queues are scheduled for execution automatically by the EM reactor. Spawned processes with no visible references are garbage-collected like any other Ruby object.
53
-
54
- Back to our code sample:
55
-
56
- pong = EM.spawn {|x, ping|
57
- puts "Pong received #{x}"
58
- ping.notify( x-1 )
59
- }
60
-
61
- This simply creates a spawned process and assigns it to the local variable pong. You can see that the spawned code block takes a numeric parameter and a reference to another spawned process. When pong is notified, it expects to receive arguments corresponding to these two parameters. It simply prints out the number it receives as the first argument. Then it notifies the spawned process referenced by the second argument, passing it the first argument minus 1.
62
-
63
- And then the block ends, which is crucial because otherwise nothing else can run. (Remember that in LC, scheduled entities run to completion and are never preempted.)
64
-
65
- On to the next bit of the code sample:
66
-
67
- ping = EM.spawn {|x|
68
- if x > 0
69
- puts "Pinging #{x}"
70
- pong.notify x, self
71
- else
72
- EM.stop
73
- end
74
- }
75
-
76
- Here, we're spawning a process that takes a single (numeric) parameter. If the parameter is greater than zero, the block writes it to the console. It then notifies the spawned process referenced by the pong local variable, passing as arguments its number argument, and a reference to itself. The latter reference, as you saw above, is used by pong to send a return notification.
77
-
78
- If the ping process receives a zero value, it will stop the reactor loop and end the program.
79
-
80
- Now we've created a pair of spawned processes, but nothing else has happened. If we stop now, the program will spin in the EM reactor loop, doing nothing at all. Our spawned processes will never be scheduled for execution.
81
-
82
- But look at the next line in the code sample:
83
-
84
- ping.notify 3
85
-
86
- This line gets the ping-pong ball rolling. We call ping's #notify method, passing the argument 3. This causes a message to be sent to the ping spawned process. The message contains the single argument, and it causes the EM reactor to schedule the ping process. And this in turn results in the execution of the Ruby code block passed to EM#spawn when ping was created. Everything else proceeds as a result of the messages that are subsequently passed to each other by the spawned processes.
87
-
88
- [TODO, present the outbound network i/o use case, and clarify that spawned processes are interleaved with normal i/o operations and don't interfere with them at all. Also, blame Erlang for the confusing term "process"]
89
-
data/ext/cplusplus.cpp DELETED
@@ -1,202 +0,0 @@
1
- /*****************************************************************************
2
-
3
- $Id$
4
-
5
- File: cplusplus.cpp
6
- Date: 27Jul07
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
- #include "project.h"
22
-
23
-
24
- namespace EM {
25
- static map<unsigned long, Eventable*> Eventables;
26
- static map<unsigned long, void(*)()> Timers;
27
- }
28
-
29
-
30
- /*******
31
- EM::Run
32
- *******/
33
-
34
- void EM::Run (void (*start_func)())
35
- {
36
- evma_set_epoll (1);
37
- evma_initialize_library (EM::Callback);
38
- if (start_func)
39
- AddTimer (0, start_func);
40
- evma_run_machine();
41
- evma_release_library();
42
- }
43
-
44
- /************
45
- EM::AddTimer
46
- ************/
47
-
48
- void EM::AddTimer (int milliseconds, void (*func)())
49
- {
50
- if (func) {
51
- const unsigned long sig = evma_install_oneshot_timer (milliseconds);
52
- #ifndef HAVE_MAKE_PAIR
53
- Timers.insert (map<unsigned long, void(*)()>::value_type (sig, func));
54
- #else
55
- Timers.insert (make_pair (sig, func));
56
- #endif
57
- }
58
- }
59
-
60
-
61
- /***************
62
- EM::StopReactor
63
- ***************/
64
-
65
- void EM::StopReactor()
66
- {
67
- evma_stop_machine();
68
- }
69
-
70
-
71
- /********************
72
- EM::Acceptor::Accept
73
- ********************/
74
-
75
- void EM::Acceptor::Accept (const unsigned long signature)
76
- {
77
- Connection *c = MakeConnection();
78
- c->Signature = signature;
79
- #ifndef HAVE_MAKE_PAIR
80
- Eventables.insert (std::map<unsigned long,EM::Eventable*>::value_type (c->Signature, c));
81
- #else
82
- Eventables.insert (make_pair (c->Signature, c));
83
- #endif
84
- c->PostInit();
85
- }
86
-
87
- /************************
88
- EM::Connection::SendData
89
- ************************/
90
-
91
- void EM::Connection::SendData (const char *data)
92
- {
93
- if (data)
94
- SendData (data, strlen (data));
95
- }
96
-
97
-
98
- /************************
99
- EM::Connection::SendData
100
- ************************/
101
-
102
- void EM::Connection::SendData (const char *data, int length)
103
- {
104
- evma_send_data_to_connection (Signature, data, length);
105
- }
106
-
107
-
108
- /*********************
109
- EM::Connection::Close
110
- *********************/
111
-
112
- void EM::Connection::Close (bool afterWriting)
113
- {
114
- evma_close_connection (Signature, afterWriting);
115
- }
116
-
117
-
118
- /***************************
119
- EM::Connection::BindConnect
120
- ***************************/
121
-
122
- void EM::Connection::BindConnect (const char *bind_addr, int bind_port, const char *host, int port)
123
- {
124
- Signature = evma_connect_to_server (bind_addr, bind_port, host, port);
125
- #ifndef HAVE_MAKE_PAIR
126
- Eventables.insert (std::map<unsigned long,EM::Eventable*>::value_type (Signature, this));
127
- #else
128
- Eventables.insert (make_pair (Signature, this));
129
- #endif
130
- }
131
-
132
- /***********************
133
- EM::Connection::Connect
134
- ***********************/
135
-
136
- void EM::Connection::Connect (const char *host, int port)
137
- {
138
- this->BindConnect(NULL, 0, host, port);
139
- }
140
-
141
- /*******************
142
- EM::Acceptor::Start
143
- *******************/
144
-
145
- void EM::Acceptor::Start (const char *host, int port)
146
- {
147
- Signature = evma_create_tcp_server (host, port);
148
- #ifndef HAVE_MAKE_PAIR
149
- Eventables.insert (std::map<unsigned long,EM::Eventable*>::value_type (Signature, this));
150
- #else
151
- Eventables.insert (make_pair (Signature, this));
152
- #endif
153
- }
154
-
155
-
156
-
157
- /************
158
- EM::Callback
159
- ************/
160
-
161
- void EM::Callback (const unsigned long sig, int ev, const char *data, const unsigned long length)
162
- {
163
- EM::Eventable *e;
164
- void (*f)();
165
-
166
- switch (ev) {
167
- case EM_TIMER_FIRED:
168
- f = Timers [length]; // actually a binding
169
- if (f)
170
- (*f)();
171
- Timers.erase (length);
172
- break;
173
-
174
- case EM_CONNECTION_READ:
175
- e = EM::Eventables [sig];
176
- e->ReceiveData (data, length);
177
- break;
178
-
179
- case EM_CONNECTION_COMPLETED:
180
- e = EM::Eventables [sig];
181
- e->ConnectionCompleted();
182
- break;
183
-
184
- case EM_CONNECTION_ACCEPTED:
185
- e = EM::Eventables [sig];
186
- e->Accept (length); // actually a binding
187
- break;
188
-
189
- case EM_CONNECTION_UNBOUND:
190
- e = EM::Eventables [sig];
191
- e->Unbind();
192
- EM::Eventables.erase (sig);
193
- delete e;
194
- break;
195
-
196
- case EM_SSL_HANDSHAKE_COMPLETED:
197
- e = EM::Eventables [sig];
198
- e->SslHandshakeCompleted();
199
- break;
200
- }
201
- }
202
-
data/ext/emwin.cpp DELETED
@@ -1,300 +0,0 @@
1
- /*****************************************************************************
2
-
3
- $Id$
4
-
5
- File: emwin.cpp
6
- Date: 05May06
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
- // THIS ENTIRE FILE IS FOR WINDOWS BUILDS ONLY
22
- // INCOMPLETE AND DISABLED FOR NOW.
23
- #ifdef xOS_WIN32
24
-
25
- #include "project.h"
26
-
27
-
28
- // Keep a global variable floating around
29
- // with the current loop time as set by the Event Machine.
30
- // This avoids the need for frequent expensive calls to time(NULL);
31
- time_t gCurrentLoopTime;
32
-
33
-
34
- /******************************
35
- EventMachine_t::EventMachine_t
36
- ******************************/
37
-
38
- EventMachine_t::EventMachine_t (void (*event_callback)(const char*, int, const char*, int)):
39
- EventCallback (event_callback),
40
- NextHeartbeatTime (0)
41
- {
42
- gTerminateSignalReceived = false;
43
- Iocp = NULL;
44
- }
45
-
46
-
47
- /*******************************
48
- EventMachine_t::~EventMachine_t
49
- *******************************/
50
-
51
- EventMachine_t::~EventMachine_t()
52
- {
53
- cerr << "EM __dt\n";
54
- if (Iocp)
55
- CloseHandle (Iocp);
56
- }
57
-
58
-
59
- /****************************
60
- EventMachine_t::ScheduleHalt
61
- ****************************/
62
-
63
- void EventMachine_t::ScheduleHalt()
64
- {
65
- /* This is how we stop the machine.
66
- * This can be called by clients. Signal handlers will probably
67
- * set the global flag.
68
- * For now this means there can only be one EventMachine ever running at a time.
69
- */
70
- gTerminateSignalReceived = true;
71
- }
72
-
73
-
74
-
75
- /*******************
76
- EventMachine_t::Run
77
- *******************/
78
-
79
- void EventMachine_t::Run()
80
- {
81
- HookControlC (true);
82
-
83
- Iocp = CreateIoCompletionPort (INVALID_HANDLE_VALUE, NULL, 0, 0);
84
- if (Iocp == NULL)
85
- throw std::runtime_error ("no completion port");
86
-
87
-
88
- DWORD nBytes, nCompletionKey;
89
- LPOVERLAPPED Overlapped;
90
-
91
- do {
92
- gCurrentLoopTime = time(NULL);
93
- // Have some kind of strategy that will dequeue maybe up to 10 completions
94
- // without running the timers as long as they are available immediately.
95
- // Otherwise in a busy server we're calling them every time through the loop.
96
- if (!_RunTimers())
97
- break;
98
- if (GetQueuedCompletionStatus (Iocp, &nBytes, &nCompletionKey, &Overlapped, 1000)) {
99
- }
100
- cerr << "+";
101
- } while (!gTerminateSignalReceived);
102
-
103
-
104
- /*
105
- while (true) {
106
- gCurrentLoopTime = time(NULL);
107
- if (!_RunTimers())
108
- break;
109
- _AddNewDescriptors();
110
- if (!_RunOnce())
111
- break;
112
- if (gTerminateSignalReceived)
113
- break;
114
- }
115
- */
116
-
117
- HookControlC (false);
118
- }
119
-
120
-
121
- /**************************
122
- EventMachine_t::_RunTimers
123
- **************************/
124
-
125
- bool EventMachine_t::_RunTimers()
126
- {
127
- // These are caller-defined timer handlers.
128
- // Return T/F to indicate whether we should continue the main loop.
129
- // We rely on the fact that multimaps sort by their keys to avoid
130
- // inspecting the whole list every time we come here.
131
- // Just keep inspecting and processing the list head until we hit
132
- // one that hasn't expired yet.
133
-
134
- while (true) {
135
- multimap<time_t,Timer_t>::iterator i = Timers.begin();
136
- if (i == Timers.end())
137
- break;
138
- if (i->first > gCurrentLoopTime)
139
- break;
140
- if (EventCallback)
141
- (*EventCallback) (NULL, EM_TIMER_FIRED, NULL, i->second.GetBinding());
142
- Timers.erase (i);
143
- }
144
- return true;
145
- }
146
-
147
-
148
- /***********************************
149
- EventMachine_t::InstallOneshotTimer
150
- ***********************************/
151
-
152
- const char *EventMachine_t::InstallOneshotTimer (int seconds)
153
- {
154
- if (Timers.size() > MaxOutstandingTimers)
155
- return false;
156
- // Don't use the global loop-time variable here, because we might
157
- // get called before the main event machine is running.
158
-
159
- Timer_t t;
160
- Timers.insert (make_pair (time(NULL) + seconds, t));
161
- return t.GetBinding();
162
- }
163
-
164
-
165
- /**********************************
166
- EventMachine_t::OpenDatagramSocket
167
- **********************************/
168
-
169
- const char *EventMachine_t::OpenDatagramSocket (const char *address, int port)
170
- {
171
- cerr << "OPEN DATAGRAM SOCKET\n";
172
- return "Unimplemented";
173
- }
174
-
175
-
176
- /*******************************
177
- EventMachine_t::CreateTcpServer
178
- *******************************/
179
-
180
- const char *EventMachine_t::CreateTcpServer (const char *server, int port)
181
- {
182
- /* Create a TCP-acceptor (server) socket and add it to the event machine.
183
- * Return the binding of the new acceptor to the caller.
184
- * This binding will be referenced when the new acceptor sends events
185
- * to indicate accepted connections.
186
- */
187
-
188
- const char *output_binding = NULL;
189
-
190
- struct sockaddr_in sin;
191
-
192
- SOCKET sd_accept = socket (AF_INET, SOCK_STREAM, 0);
193
- if (sd_accept == INVALID_SOCKET) {
194
- goto fail;
195
- }
196
-
197
- memset (&sin, 0, sizeof(sin));
198
- sin.sin_family = AF_INET;
199
- sin.sin_addr.s_addr = INADDR_ANY;
200
- sin.sin_port = htons (port);
201
-
202
- if (server && *server) {
203
- sin.sin_addr.s_addr = inet_addr (server);
204
- if (sin.sin_addr.s_addr == INADDR_NONE) {
205
- hostent *hp = gethostbyname (server);
206
- if (hp == NULL) {
207
- //__warning ("hostname not resolved: ", server);
208
- goto fail;
209
- }
210
- sin.sin_addr.s_addr = ((in_addr*)(hp->h_addr))->s_addr;
211
- }
212
- }
213
-
214
-
215
- // No need to set reuseaddr on Windows.
216
-
217
-
218
- if (bind (sd_accept, (struct sockaddr*)&sin, sizeof(sin))) {
219
- //__warning ("binding failed");
220
- goto fail;
221
- }
222
-
223
- if (listen (sd_accept, 100)) {
224
- //__warning ("listen failed");
225
- goto fail;
226
- }
227
-
228
- { // Looking good.
229
- AcceptorDescriptor *ad = new AcceptorDescriptor (this, sd_accept);
230
- if (!ad)
231
- throw std::runtime_error ("unable to allocate acceptor");
232
- Add (ad);
233
- output_binding = ad->GetBinding();
234
-
235
- CreateIoCompletionPort ((HANDLE)sd_accept, Iocp, NULL, 0);
236
- SOCKET sd = socket (AF_INET, SOCK_STREAM, 0);
237
- CreateIoCompletionPort ((HANDLE)sd, Iocp, NULL, 0);
238
- AcceptEx (sd_accept, sd,
239
- }
240
-
241
- return output_binding;
242
-
243
- fail:
244
- if (sd_accept != INVALID_SOCKET)
245
- closesocket (sd_accept);
246
- return NULL;
247
- }
248
-
249
-
250
- /*******************************
251
- EventMachine_t::ConnectToServer
252
- *******************************/
253
-
254
- const char *EventMachine_t::ConnectToServer (const char *server, int port)
255
- {
256
- if (!server || !*server || !port)
257
- return NULL;
258
-
259
- sockaddr_in pin;
260
- unsigned long HostAddr;
261
-
262
- HostAddr = inet_addr (server);
263
- if (HostAddr == INADDR_NONE) {
264
- hostent *hp = gethostbyname (server);
265
- if (!hp)
266
- return NULL;
267
- HostAddr = ((in_addr*)(hp->h_addr))->s_addr;
268
- }
269
-
270
- memset (&pin, 0, sizeof(pin));
271
- pin.sin_family = AF_INET;
272
- pin.sin_addr.s_addr = HostAddr;
273
- pin.sin_port = htons (port);
274
-
275
- int sd = socket (AF_INET, SOCK_STREAM, 0);
276
- if (sd == INVALID_SOCKET)
277
- return NULL;
278
-
279
-
280
- LPOVERLAPPED olap = (LPOVERLAPPED) calloc (1, sizeof (OVERLAPPED));
281
- cerr << "I'm dying now\n";
282
- throw runtime_error ("UNIMPLEMENTED!!!\n");
283
-
284
- }
285
-
286
-
287
-
288
- /*******************
289
- EventMachine_t::Add
290
- *******************/
291
-
292
- void EventMachine_t::Add (EventableDescriptor *ed)
293
- {
294
- cerr << "ADD\n";
295
- }
296
-
297
-
298
-
299
- #endif // OS_WIN32
300
-
data/ext/emwin.h DELETED
@@ -1,94 +0,0 @@
1
- /*****************************************************************************
2
-
3
- $Id$
4
-
5
- File: emwin.h
6
- Date: 05May06
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
- // THIS ENTIRE FILE IS FOR WINDOWS BUILDS ONLY.
22
- // INCOMPLETE AND DISABLED FOR NOW.
23
- #ifdef xOS_WIN32
24
-
25
- #ifndef __EventMachine__H_
26
- #define __EventMachine__H_
27
-
28
-
29
- extern time_t gCurrentLoopTime;
30
-
31
- class EventableDescriptor;
32
-
33
-
34
- /********************
35
- class EventMachine_t
36
- ********************/
37
-
38
- class EventMachine_t
39
- {
40
- public:
41
- EventMachine_t (void(*event_callback)(const char*, int, const char*, int));
42
- virtual ~EventMachine_t();
43
-
44
- void Run();
45
- void ScheduleHalt();
46
- const char *InstallOneshotTimer (int);
47
- const char *ConnectToServer (const char *, int);
48
- const char *CreateTcpServer (const char *, int);
49
- const char *OpenDatagramSocket (const char *, int);
50
-
51
- void Add (EventableDescriptor*);
52
-
53
- public:
54
- enum { // Event names
55
- TIMER_FIRED = 100,
56
- CONNECTION_READ = 101,
57
- CONNECTION_UNBOUND = 102,
58
- CONNECTION_ACCEPTED = 103,
59
- CONNECTION_COMPLETED = 104,
60
- LOOPBREAK_SIGNAL = 105
61
- };
62
-
63
- private:
64
- HANDLE Iocp;
65
-
66
- private:
67
- bool _RunOnce();
68
- bool _RunTimers();
69
- void _AddNewDescriptors();
70
-
71
- private:
72
- enum {
73
- MaxOutstandingTimers = 40,
74
- HeartbeatInterval = 2
75
- };
76
- void (*EventCallback)(const char*, int, const char*, int);
77
-
78
- class Timer_t: public Bindable_t {
79
- };
80
-
81
- multimap<time_t, Timer_t> Timers;
82
- vector<EventableDescriptor*> Descriptors;
83
- vector<EventableDescriptor*> NewDescriptors;
84
-
85
- time_t NextHeartbeatTime;
86
- };
87
-
88
-
89
-
90
-
91
- #endif // __EventMachine__H_
92
-
93
- #endif // OS_WIN32
94
-
data/ext/epoll.cpp DELETED
@@ -1,26 +0,0 @@
1
- /*****************************************************************************
2
-
3
- $Id$
4
-
5
- File: epoll.cpp
6
- Date: 06Jun07
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
- #ifdef HAVE_EPOLL
22
-
23
- #include "project.h"
24
-
25
- #endif // HAVE_EPOLL
26
-