eventmachine 0.12.10-x86-mswin32-60 → 1.0.0.beta.2-x86-mswin32-60

Sign up to get free protection for your applications and to get access to all the features.
Files changed (150) hide show
  1. data/.gitignore +2 -0
  2. data/Gemfile +1 -0
  3. data/README +80 -81
  4. data/Rakefile +7 -370
  5. data/docs/COPYING +60 -60
  6. data/docs/ChangeLog +211 -211
  7. data/docs/DEFERRABLES +246 -133
  8. data/docs/EPOLL +141 -141
  9. data/docs/GNU +281 -281
  10. data/docs/INSTALL +13 -13
  11. data/docs/KEYBOARD +42 -38
  12. data/docs/LEGAL +25 -25
  13. data/docs/LIGHTWEIGHT_CONCURRENCY +130 -70
  14. data/docs/PURE_RUBY +75 -75
  15. data/docs/RELEASE_NOTES +94 -94
  16. data/docs/SMTP +4 -2
  17. data/docs/SPAWNED_PROCESSES +148 -89
  18. data/docs/TODO +8 -8
  19. data/eventmachine.gemspec +19 -26
  20. data/examples/ex_channel.rb +42 -42
  21. data/examples/ex_queue.rb +2 -2
  22. data/examples/ex_tick_loop_array.rb +15 -0
  23. data/examples/ex_tick_loop_counter.rb +32 -0
  24. data/examples/helper.rb +1 -1
  25. data/ext/binder.cpp +0 -1
  26. data/ext/cmain.cpp +36 -25
  27. data/ext/ed.cpp +104 -113
  28. data/ext/ed.h +24 -30
  29. data/ext/em.cpp +349 -283
  30. data/ext/em.h +25 -29
  31. data/ext/eventmachine.h +5 -4
  32. data/ext/extconf.rb +58 -49
  33. data/ext/fastfilereader/extconf.rb +5 -3
  34. data/ext/fastfilereader/mapper.cpp +214 -214
  35. data/ext/fastfilereader/mapper.h +59 -59
  36. data/ext/fastfilereader/rubymain.cpp +127 -127
  37. data/ext/kb.cpp +1 -3
  38. data/ext/page.cpp +107 -107
  39. data/ext/page.h +51 -51
  40. data/ext/pipe.cpp +9 -11
  41. data/ext/project.h +12 -8
  42. data/ext/rubymain.cpp +138 -104
  43. data/java/.classpath +8 -8
  44. data/java/.project +17 -17
  45. data/java/src/com/rubyeventmachine/EmReactor.java +1 -0
  46. data/java/src/com/rubyeventmachine/EmReactorException.java +40 -40
  47. data/lib/em/buftok.rb +138 -138
  48. data/lib/em/callback.rb +25 -25
  49. data/lib/em/channel.rb +1 -1
  50. data/lib/em/connection.rb +6 -1
  51. data/lib/em/deferrable.rb +16 -2
  52. data/lib/em/file_watch.rb +53 -53
  53. data/lib/em/future.rb +61 -61
  54. data/lib/em/iterator.rb +270 -0
  55. data/lib/em/messages.rb +66 -66
  56. data/lib/em/process_watch.rb +43 -43
  57. data/lib/em/protocols.rb +1 -1
  58. data/lib/em/protocols/header_and_content.rb +138 -138
  59. data/lib/em/protocols/httpclient.rb +267 -262
  60. data/lib/em/protocols/line_protocol.rb +28 -0
  61. data/lib/em/protocols/memcache.rb +322 -322
  62. data/lib/em/protocols/postgres3.rb +247 -247
  63. data/lib/em/protocols/saslauth.rb +175 -175
  64. data/lib/em/protocols/smtpserver.rb +640 -547
  65. data/lib/em/protocols/stomp.rb +200 -200
  66. data/lib/em/protocols/tcptest.rb +52 -52
  67. data/lib/{pr_eventmachine.rb → em/pure_ruby.rb} +1013 -1022
  68. data/lib/em/queue.rb +1 -0
  69. data/lib/em/spawnable.rb +85 -85
  70. data/lib/em/streamer.rb +130 -130
  71. data/lib/em/tick_loop.rb +85 -0
  72. data/lib/em/timers.rb +2 -1
  73. data/lib/em/version.rb +1 -1
  74. data/lib/eventmachine.rb +40 -84
  75. data/lib/jeventmachine.rb +2 -1
  76. data/lib/rubyeventmachine.rb +2 -0
  77. data/setup.rb +1585 -1585
  78. data/tasks/doc.rake +30 -0
  79. data/tasks/package.rake +85 -0
  80. data/tasks/test.rake +6 -0
  81. data/tests/client.crt +31 -31
  82. data/tests/client.key +51 -51
  83. data/tests/test_attach.rb +13 -3
  84. data/tests/test_basic.rb +60 -95
  85. data/tests/test_channel.rb +3 -2
  86. data/tests/test_defer.rb +49 -47
  87. data/tests/test_deferrable.rb +35 -0
  88. data/tests/test_error_handler.rb +35 -35
  89. data/tests/test_errors.rb +82 -82
  90. data/tests/test_exc.rb +55 -55
  91. data/tests/test_file_watch.rb +49 -49
  92. data/tests/test_futures.rb +198 -198
  93. data/tests/test_handler_check.rb +36 -36
  94. data/tests/test_hc.rb +190 -218
  95. data/tests/test_httpclient.rb +227 -218
  96. data/tests/test_httpclient2.rb +3 -2
  97. data/tests/test_inactivity_timeout.rb +3 -3
  98. data/tests/test_kb.rb +60 -60
  99. data/tests/test_ltp.rb +13 -5
  100. data/tests/test_ltp2.rb +317 -317
  101. data/tests/test_next_tick.rb +1 -1
  102. data/tests/test_object_protocol.rb +36 -36
  103. data/tests/test_pending_connect_timeout.rb +2 -2
  104. data/tests/test_process_watch.rb +50 -48
  105. data/tests/test_proxy_connection.rb +52 -0
  106. data/tests/test_pure.rb +134 -125
  107. data/tests/test_queue.rb +44 -44
  108. data/tests/test_running.rb +42 -42
  109. data/tests/test_sasl.rb +72 -72
  110. data/tests/test_send_file.rb +251 -242
  111. data/tests/test_servers.rb +76 -76
  112. data/tests/test_smtpclient.rb +83 -83
  113. data/tests/test_smtpserver.rb +85 -85
  114. data/tests/test_spawn.rb +322 -322
  115. data/tests/test_ssl_methods.rb +49 -49
  116. data/tests/test_ssl_verify.rb +82 -82
  117. data/tests/test_tick_loop.rb +59 -0
  118. data/tests/test_timers.rb +13 -15
  119. data/tests/test_ud.rb +36 -36
  120. data/tests/testem.rb +31 -31
  121. metadata +66 -51
  122. data/ext/cplusplus.cpp +0 -202
  123. data/ext/emwin.cpp +0 -300
  124. data/ext/emwin.h +0 -94
  125. data/ext/epoll.cpp +0 -26
  126. data/ext/epoll.h +0 -25
  127. data/ext/eventmachine_cpp.h +0 -96
  128. data/ext/files.cpp +0 -94
  129. data/ext/files.h +0 -65
  130. data/ext/sigs.cpp +0 -89
  131. data/ext/sigs.h +0 -32
  132. data/java/src/com/rubyeventmachine/application/Application.java +0 -194
  133. data/java/src/com/rubyeventmachine/application/Connection.java +0 -74
  134. data/java/src/com/rubyeventmachine/application/ConnectionFactory.java +0 -37
  135. data/java/src/com/rubyeventmachine/application/DefaultConnectionFactory.java +0 -46
  136. data/java/src/com/rubyeventmachine/application/PeriodicTimer.java +0 -38
  137. data/java/src/com/rubyeventmachine/application/Timer.java +0 -54
  138. data/java/src/com/rubyeventmachine/tests/ApplicationTest.java +0 -109
  139. data/java/src/com/rubyeventmachine/tests/ConnectTest.java +0 -148
  140. data/java/src/com/rubyeventmachine/tests/EMTest.java +0 -80
  141. data/java/src/com/rubyeventmachine/tests/TestDatagrams.java +0 -53
  142. data/java/src/com/rubyeventmachine/tests/TestServers.java +0 -75
  143. data/java/src/com/rubyeventmachine/tests/TestTimers.java +0 -90
  144. data/lib/evma.rb +0 -32
  145. data/lib/evma/callback.rb +0 -32
  146. data/lib/evma/container.rb +0 -75
  147. data/lib/evma/factory.rb +0 -77
  148. data/lib/evma/protocol.rb +0 -87
  149. data/lib/evma/reactor.rb +0 -48
  150. data/web/whatis +0 -7
data/ext/page.h CHANGED
@@ -1,51 +1,51 @@
1
- /*****************************************************************************
2
-
3
- $Id$
4
-
5
- File: page.h
6
- Date: 30Apr06
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 __PageManager__H_
22
- #define __PageManager__H_
23
-
24
-
25
- /**************
26
- class PageList
27
- **************/
28
-
29
- class PageList
30
- {
31
- struct Page {
32
- Page (const char *b, size_t s): Buffer(b), Size(s) {}
33
- const char *Buffer;
34
- size_t Size;
35
- };
36
-
37
- public:
38
- PageList();
39
- virtual ~PageList();
40
-
41
- void Push (const char*, int);
42
- bool HasPages();
43
- void Front (const char**, int*);
44
- void PopFront();
45
-
46
- private:
47
- deque<Page> Pages;
48
- };
49
-
50
-
51
- #endif // __PageManager__H_
1
+ /*****************************************************************************
2
+
3
+ $Id$
4
+
5
+ File: page.h
6
+ Date: 30Apr06
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 __PageManager__H_
22
+ #define __PageManager__H_
23
+
24
+
25
+ /**************
26
+ class PageList
27
+ **************/
28
+
29
+ class PageList
30
+ {
31
+ struct Page {
32
+ Page (const char *b, size_t s): Buffer(b), Size(s) {}
33
+ const char *Buffer;
34
+ size_t Size;
35
+ };
36
+
37
+ public:
38
+ PageList();
39
+ virtual ~PageList();
40
+
41
+ void Push (const char*, int);
42
+ bool HasPages();
43
+ void Front (const char**, int*);
44
+ void PopFront();
45
+
46
+ private:
47
+ deque<Page> Pages;
48
+ };
49
+
50
+
51
+ #endif // __PageManager__H_
@@ -30,8 +30,6 @@ PipeDescriptor::PipeDescriptor
30
30
  PipeDescriptor::PipeDescriptor (int fd, pid_t subpid, EventMachine_t *parent_em):
31
31
  EventableDescriptor (fd, parent_em),
32
32
  bReadAttemptedAfterClose (false),
33
- LastIo (gCurrentLoopTime),
34
- InactivityTimeout (0),
35
33
  OutboundDataSize (0),
36
34
  SubprocessPid (subpid)
37
35
  {
@@ -104,22 +102,22 @@ PipeDescriptor::~PipeDescriptor()
104
102
  struct timespec req = {0, 50000000}; // 0.05s
105
103
  int n;
106
104
 
107
- // wait 0.25s for the process to die
108
- for (n=0; n<5; n++) {
105
+ // wait 0.5s for the process to die
106
+ for (n=0; n<10; n++) {
109
107
  if (waitpid (SubprocessPid, &(MyEventMachine->SubprocessExitStatus), WNOHANG) != 0) return;
110
108
  nanosleep (&req, NULL);
111
109
  }
112
110
 
113
- // send SIGTERM and wait another 0.5s
111
+ // send SIGTERM and wait another 1s
114
112
  kill (SubprocessPid, SIGTERM);
115
- for (n=0; n<10; n++) {
113
+ for (n=0; n<20; n++) {
116
114
  nanosleep (&req, NULL);
117
115
  if (waitpid (SubprocessPid, &(MyEventMachine->SubprocessExitStatus), WNOHANG) != 0) return;
118
116
  }
119
117
 
120
- // send SIGKILL and wait another 1s
118
+ // send SIGKILL and wait another 5s
121
119
  kill (SubprocessPid, SIGKILL);
122
- for (n=0; n<20; n++) {
120
+ for (n=0; n<100; n++) {
123
121
  nanosleep (&req, NULL);
124
122
  if (waitpid (SubprocessPid, &(MyEventMachine->SubprocessExitStatus), WNOHANG) != 0) return;
125
123
  }
@@ -143,7 +141,7 @@ void PipeDescriptor::Read()
143
141
  return;
144
142
  }
145
143
 
146
- LastIo = gCurrentLoopTime;
144
+ LastActivity = MyEventMachine->GetCurrentLoopTime();
147
145
 
148
146
  int total_bytes_read = 0;
149
147
  char readbuffer [16 * 1024];
@@ -203,7 +201,7 @@ void PipeDescriptor::Write()
203
201
  int sd = GetSocket();
204
202
  assert (sd != INVALID_SOCKET);
205
203
 
206
- LastIo = gCurrentLoopTime;
204
+ LastActivity = MyEventMachine->GetCurrentLoopTime();
207
205
  char output_buffer [16 * 1024];
208
206
  size_t nbytes = 0;
209
207
 
@@ -268,7 +266,7 @@ PipeDescriptor::Heartbeat
268
266
  void PipeDescriptor::Heartbeat()
269
267
  {
270
268
  // If an inactivity timeout is defined, then check for it.
271
- if (InactivityTimeout && ((gCurrentLoopTime - LastIo) >= InactivityTimeout))
269
+ if (InactivityTimeout && ((MyEventMachine->GetCurrentLoopTime() - LastActivity) >= InactivityTimeout))
272
270
  ScheduleClose (false);
273
271
  //bCloseNow = true;
274
272
  }
@@ -55,8 +55,8 @@ See the file COPYING for complete licensing information.
55
55
  #include <netinet/tcp.h>
56
56
  #include <arpa/inet.h>
57
57
  #include <pwd.h>
58
+ #include <string.h>
58
59
  typedef int SOCKET;
59
- #define closesocket close
60
60
  #define INVALID_SOCKET -1
61
61
  #define SOCKET_ERROR -1
62
62
  #ifdef OS_SOLARIS8
@@ -96,6 +96,9 @@ typedef int socklen_t;
96
96
  typedef int pid_t;
97
97
  #endif
98
98
 
99
+ #if !defined(_MSC_VER) || _MSC_VER > 1400
100
+ #include <stdint.h>
101
+ #endif
99
102
 
100
103
  using namespace std;
101
104
 
@@ -134,18 +137,19 @@ static inline int inotify_rm_watch (int fd, __u32 wd) { return syscall (__NR_ino
134
137
  #include <sys/uio.h>
135
138
  #endif
136
139
 
140
+ #if __cplusplus
141
+ extern "C" {
142
+ #endif
143
+ typedef void (*EMCallback)(const unsigned long, int, const char*, const unsigned long);
144
+ #if __cplusplus
145
+ }
146
+ #endif
147
+
137
148
  #include "binder.h"
138
149
  #include "em.h"
139
- #include "epoll.h"
140
- #include "sigs.h"
141
150
  #include "ed.h"
142
- #include "files.h"
143
151
  #include "page.h"
144
152
  #include "ssl.h"
145
153
  #include "eventmachine.h"
146
- #include "eventmachine_cpp.h"
147
-
148
-
149
-
150
154
 
151
155
  #endif // __Project__H_
@@ -31,6 +31,8 @@ Statics
31
31
 
32
32
  static VALUE EmModule;
33
33
  static VALUE EmConnection;
34
+ static VALUE EmConnsHash;
35
+ static VALUE EmTimersHash;
34
36
 
35
37
  static VALUE EM_eConnectionError;
36
38
  static VALUE EM_eUnknownTimerFired;
@@ -51,89 +53,117 @@ static VALUE Intern_ssl_verify_peer;
51
53
  static VALUE Intern_notify_readable;
52
54
  static VALUE Intern_notify_writable;
53
55
  static VALUE Intern_proxy_target_unbound;
56
+ static VALUE Intern_proxy_completed;
57
+ static VALUE Intern_connection_completed;
54
58
 
55
59
  static VALUE rb_cProcStatus;
56
60
 
57
61
  struct em_event {
58
- unsigned long a1;
59
- int a2;
60
- const char *a3;
61
- unsigned long a4;
62
+ unsigned long signature;
63
+ int event;
64
+ const char *data_str;
65
+ unsigned long data_num;
62
66
  };
63
67
 
68
+ static inline VALUE ensure_conn(const unsigned long signature)
69
+ {
70
+ VALUE conn = rb_hash_aref (EmConnsHash, ULONG2NUM (signature));
71
+ if (conn == Qnil)
72
+ rb_raise (EM_eConnectionNotBound, "unknown connection: %lu", signature);
73
+ return conn;
74
+ }
75
+
76
+
64
77
  /****************
65
78
  t_event_callback
66
79
  ****************/
67
80
 
68
- static void event_callback (struct em_event* e)
69
- {
70
- const unsigned long a1 = e->a1;
71
- int a2 = e->a2;
72
- const char *a3 = e->a3;
73
- const unsigned long a4 = e->a4;
74
-
75
- if (a2 == EM_CONNECTION_READ) {
76
- VALUE t = rb_ivar_get (EmModule, Intern_at_conns);
77
- VALUE q = rb_hash_aref (t, ULONG2NUM (a1));
78
- if (q == Qnil)
79
- rb_raise (EM_eConnectionNotBound, "received %lu bytes of data for unknown signature: %lu", a4, a1);
80
- rb_funcall (q, Intern_receive_data, 1, rb_str_new (a3, a4));
81
- }
82
- else if (a2 == EM_CONNECTION_NOTIFY_READABLE) {
83
- VALUE t = rb_ivar_get (EmModule, Intern_at_conns);
84
- VALUE q = rb_hash_aref (t, ULONG2NUM (a1));
85
- if (q == Qnil)
86
- rb_raise (EM_eConnectionNotBound, "unknown connection: %lu", a1);
87
- rb_funcall (q, Intern_notify_readable, 0);
88
- }
89
- else if (a2 == EM_CONNECTION_NOTIFY_WRITABLE) {
90
- VALUE t = rb_ivar_get (EmModule, Intern_at_conns);
91
- VALUE q = rb_hash_aref (t, ULONG2NUM (a1));
92
- if (q == Qnil)
93
- rb_raise (EM_eConnectionNotBound, "unknown connection: %lu", a1);
94
- rb_funcall (q, Intern_notify_writable, 0);
95
- }
96
- else if (a2 == EM_LOOPBREAK_SIGNAL) {
97
- rb_funcall (EmModule, Intern_run_deferred_callbacks, 0);
98
- }
99
- else if (a2 == EM_TIMER_FIRED) {
100
- VALUE t = rb_ivar_get (EmModule, Intern_at_timers);
101
- VALUE q = rb_funcall (t, Intern_delete, 1, ULONG2NUM (a4));
102
- if (q == Qnil) {
103
- rb_raise (EM_eUnknownTimerFired, "no such timer: %lu", a4);
104
- } else if (q == Qfalse) {
105
- /* Timer Canceled */
106
- } else {
107
- rb_funcall (q, Intern_call, 0);
81
+ static inline void event_callback (struct em_event* e)
82
+ {
83
+ const unsigned long signature = e->signature;
84
+ int event = e->event;
85
+ const char *data_str = e->data_str;
86
+ const unsigned long data_num = e->data_num;
87
+
88
+ switch (event) {
89
+ case EM_CONNECTION_READ:
90
+ {
91
+ VALUE conn = rb_hash_aref (EmConnsHash, ULONG2NUM (signature));
92
+ if (conn == Qnil)
93
+ rb_raise (EM_eConnectionNotBound, "received %lu bytes of data for unknown signature: %lu", data_num, signature);
94
+ rb_funcall (conn, Intern_receive_data, 1, rb_str_new (data_str, data_num));
95
+ return;
96
+ }
97
+ case EM_CONNECTION_ACCEPTED:
98
+ case EM_CONNECTION_UNBOUND:
99
+ {
100
+ rb_funcall (EmModule, Intern_event_callback, 3, ULONG2NUM(signature), INT2FIX(event), data_str ? rb_str_new(data_str,data_num) : ULONG2NUM(data_num));
101
+ return;
102
+ }
103
+ case EM_CONNECTION_COMPLETED:
104
+ {
105
+ VALUE conn = ensure_conn(signature);
106
+ rb_funcall (conn, Intern_connection_completed, 0);
107
+ return;
108
+ }
109
+ case EM_CONNECTION_NOTIFY_READABLE:
110
+ {
111
+ VALUE conn = ensure_conn(signature);
112
+ rb_funcall (conn, Intern_notify_readable, 0);
113
+ return;
114
+ }
115
+ case EM_CONNECTION_NOTIFY_WRITABLE:
116
+ {
117
+ VALUE conn = ensure_conn(signature);
118
+ rb_funcall (conn, Intern_notify_writable, 0);
119
+ return;
120
+ }
121
+ case EM_LOOPBREAK_SIGNAL:
122
+ {
123
+ rb_funcall (EmModule, Intern_run_deferred_callbacks, 0);
124
+ return;
125
+ }
126
+ case EM_TIMER_FIRED:
127
+ {
128
+ VALUE timer = rb_funcall (EmTimersHash, Intern_delete, 1, ULONG2NUM (data_num));
129
+ if (timer == Qnil) {
130
+ rb_raise (EM_eUnknownTimerFired, "no such timer: %lu", data_num);
131
+ } else if (timer == Qfalse) {
132
+ /* Timer Canceled */
133
+ } else {
134
+ rb_funcall (timer, Intern_call, 0);
135
+ }
136
+ return;
137
+ }
138
+ #ifdef WITH_SSL
139
+ case EM_SSL_HANDSHAKE_COMPLETED:
140
+ {
141
+ VALUE conn = ensure_conn(signature);
142
+ rb_funcall (conn, Intern_ssl_handshake_completed, 0);
143
+ return;
144
+ }
145
+ case EM_SSL_VERIFY:
146
+ {
147
+ VALUE conn = ensure_conn(signature);
148
+ VALUE should_accept = rb_funcall (conn, Intern_ssl_verify_peer, 1, rb_str_new(data_str, data_num));
149
+ if (RTEST(should_accept))
150
+ evma_accept_ssl_peer (signature);
151
+ return;
152
+ }
153
+ #endif
154
+ case EM_PROXY_TARGET_UNBOUND:
155
+ {
156
+ VALUE conn = ensure_conn(signature);
157
+ rb_funcall (conn, Intern_proxy_target_unbound, 0);
158
+ return;
159
+ }
160
+ case EM_PROXY_COMPLETED:
161
+ {
162
+ VALUE conn = ensure_conn(signature);
163
+ rb_funcall (conn, Intern_proxy_completed, 0);
164
+ return;
108
165
  }
109
166
  }
110
- #ifdef WITH_SSL
111
- else if (a2 == EM_SSL_HANDSHAKE_COMPLETED) {
112
- VALUE t = rb_ivar_get (EmModule, Intern_at_conns);
113
- VALUE q = rb_hash_aref (t, ULONG2NUM (a1));
114
- if (q == Qnil)
115
- rb_raise (EM_eConnectionNotBound, "unknown connection: %lu", a1);
116
- rb_funcall (q, Intern_ssl_handshake_completed, 0);
117
- }
118
- else if (a2 == EM_SSL_VERIFY) {
119
- VALUE t = rb_ivar_get (EmModule, Intern_at_conns);
120
- VALUE q = rb_hash_aref (t, ULONG2NUM (a1));
121
- if (q == Qnil)
122
- rb_raise (EM_eConnectionNotBound, "unknown connection: %lu", a1);
123
- VALUE r = rb_funcall (q, Intern_ssl_verify_peer, 1, rb_str_new(a3, a4));
124
- if (RTEST(r))
125
- evma_accept_ssl_peer (a1);
126
- }
127
- #endif
128
- else if (a2 == EM_PROXY_TARGET_UNBOUND) {
129
- VALUE t = rb_ivar_get (EmModule, Intern_at_conns);
130
- VALUE q = rb_hash_aref (t, ULONG2NUM (a1));
131
- if (q == Qnil)
132
- rb_raise (EM_eConnectionNotBound, "unknown connection: %lu", a1);
133
- rb_funcall (q, Intern_proxy_target_unbound, 0);
134
- }
135
- else
136
- rb_funcall (EmModule, Intern_event_callback, 3, ULONG2NUM(a1), INT2FIX(a2), a3 ? rb_str_new(a3,a4) : ULONG2NUM(a4));
137
167
  }
138
168
 
139
169
  /*******************
@@ -150,13 +180,13 @@ static void event_error_handler(VALUE unused, VALUE err)
150
180
  event_callback_wrapper
151
181
  **********************/
152
182
 
153
- static void event_callback_wrapper (const unsigned long a1, int a2, const char *a3, const unsigned long a4)
183
+ static void event_callback_wrapper (const unsigned long signature, int event, const char *data_str, const unsigned long data_num)
154
184
  {
155
185
  struct em_event e;
156
- e.a1 = a1;
157
- e.a2 = a2;
158
- e.a3 = a3;
159
- e.a4 = a4;
186
+ e.signature = signature;
187
+ e.event = event;
188
+ e.data_str = data_str;
189
+ e.data_num = data_num;
160
190
 
161
191
  if (!rb_ivar_defined(EmModule, Intern_at_error_handler))
162
192
  event_callback(&e);
@@ -170,7 +200,11 @@ t_initialize_event_machine
170
200
 
171
201
  static VALUE t_initialize_event_machine (VALUE self)
172
202
  {
173
- evma_initialize_library (event_callback_wrapper);
203
+ EmConnsHash = rb_ivar_get (EmModule, Intern_at_conns);
204
+ EmTimersHash = rb_ivar_get (EmModule, Intern_at_timers);
205
+ assert(EmConnsHash != Qnil);
206
+ assert(EmTimersHash != Qnil);
207
+ evma_initialize_library ((EMCallback)event_callback_wrapper);
174
208
  return Qnil;
175
209
  }
176
210
 
@@ -208,7 +242,7 @@ static VALUE t_start_server (VALUE self, VALUE server, VALUE port)
208
242
  {
209
243
  const unsigned long f = evma_create_tcp_server (StringValuePtr(server), FIX2INT(port));
210
244
  if (!f)
211
- rb_raise (rb_eRuntimeError, "no acceptor");
245
+ rb_raise (rb_eRuntimeError, "no acceptor (port is in use or requires root privileges)");
212
246
  return ULONG2NUM (f);
213
247
  }
214
248
 
@@ -467,6 +501,7 @@ static VALUE t_connect_server (VALUE self, VALUE server, VALUE port)
467
501
  } catch (std::runtime_error e) {
468
502
  rb_raise (EM_eConnectionError, e.what());
469
503
  }
504
+ return Qnil;
470
505
  }
471
506
 
472
507
  /*********************
@@ -487,6 +522,7 @@ static VALUE t_bind_connect_server (VALUE self, VALUE bind_addr, VALUE bind_port
487
522
  } catch (std::runtime_error e) {
488
523
  rb_raise (EM_eConnectionError, e.what());
489
524
  }
525
+ return Qnil;
490
526
  }
491
527
 
492
528
  /*********************
@@ -701,18 +737,6 @@ static VALUE t_setuid_string (VALUE self, VALUE username)
701
737
 
702
738
 
703
739
 
704
- /*************
705
- t__write_file
706
- *************/
707
-
708
- static VALUE t__write_file (VALUE self, VALUE filename)
709
- {
710
- const unsigned long f = evma__write_file (StringValuePtr (filename));
711
- if (!f)
712
- rb_raise (rb_eRuntimeError, "file not opened");
713
- return ULONG2NUM (f);
714
- }
715
-
716
740
  /**************
717
741
  t_invoke_popen
718
742
  **************/
@@ -725,9 +749,9 @@ static VALUE t_invoke_popen (VALUE self, VALUE cmd)
725
749
  #else
726
750
  int len = RARRAY (cmd)->len;
727
751
  #endif
728
- if (len > 98)
752
+ if (len >= 2048)
729
753
  rb_raise (rb_eRuntimeError, "too many arguments to popen");
730
- char *strings [100];
754
+ char *strings [2048];
731
755
  for (int i=0; i < len; i++) {
732
756
  VALUE ix = INT2FIX (i);
733
757
  VALUE s = rb_ary_aref (1, &ix, cmd);
@@ -769,8 +793,9 @@ static VALUE t_watch_filename (VALUE self, VALUE fname)
769
793
  try {
770
794
  return ULONG2NUM(evma_watch_filename(StringValuePtr(fname)));
771
795
  } catch (std::runtime_error e) {
772
- rb_sys_fail(e.what());
796
+ rb_raise (EM_eUnsupported, e.what());
773
797
  }
798
+ return Qnil;
774
799
  }
775
800
 
776
801
 
@@ -794,8 +819,9 @@ static VALUE t_watch_pid (VALUE self, VALUE pid)
794
819
  try {
795
820
  return ULONG2NUM(evma_watch_pid(NUM2INT(pid)));
796
821
  } catch (std::runtime_error e) {
797
- rb_sys_fail(e.what());
822
+ rb_raise (EM_eUnsupported, e.what());
798
823
  }
824
+ return Qnil;
799
825
  }
800
826
 
801
827
 
@@ -972,11 +998,12 @@ static VALUE t_get_loop_time (VALUE self)
972
998
  static ID at = rb_intern("at");
973
999
  #endif
974
1000
 
975
- if (gCurrentLoopTime != 0) {
1001
+ uint64_t current_time = evma_get_current_loop_time();
1002
+ if (current_time != 0) {
976
1003
  #ifndef HAVE_RB_TIME_NEW
977
- return rb_funcall(cTime, at, 2, INT2NUM(gCurrentLoopTime / 1000000), INT2NUM(gCurrentLoopTime % 1000000));
1004
+ return rb_funcall(cTime, at, 2, INT2NUM(current_time / 1000000), INT2NUM(current_time % 1000000));
978
1005
  #else
979
- return rb_time_new(gCurrentLoopTime / 1000000, gCurrentLoopTime % 1000000);
1006
+ return rb_time_new(current_time / 1000000, current_time % 1000000);
980
1007
  #endif
981
1008
  }
982
1009
  return Qnil;
@@ -987,9 +1014,13 @@ static VALUE t_get_loop_time (VALUE self)
987
1014
  t_start_proxy
988
1015
  **************/
989
1016
 
990
- static VALUE t_start_proxy (VALUE self, VALUE from, VALUE to, VALUE bufsize)
1017
+ static VALUE t_start_proxy (VALUE self, VALUE from, VALUE to, VALUE bufsize, VALUE length)
991
1018
  {
992
- evma_start_proxy(NUM2ULONG (from), NUM2ULONG (to), NUM2ULONG(bufsize));
1019
+ try {
1020
+ evma_start_proxy(NUM2ULONG (from), NUM2ULONG (to), NUM2ULONG(bufsize), NUM2ULONG(length));
1021
+ } catch (std::runtime_error e) {
1022
+ rb_raise (EM_eConnectionError, e.what());
1023
+ }
993
1024
  return Qnil;
994
1025
  }
995
1026
 
@@ -1000,7 +1031,11 @@ t_stop_proxy
1000
1031
 
1001
1032
  static VALUE t_stop_proxy (VALUE self, VALUE from)
1002
1033
  {
1003
- evma_stop_proxy(NUM2ULONG (from));
1034
+ try{
1035
+ evma_stop_proxy(NUM2ULONG (from));
1036
+ } catch (std::runtime_error e) {
1037
+ rb_raise (EM_eConnectionError, e.what());
1038
+ }
1004
1039
  return Qnil;
1005
1040
  }
1006
1041
 
@@ -1054,6 +1089,8 @@ extern "C" void Init_rubyeventmachine()
1054
1089
  Intern_notify_readable = rb_intern ("notify_readable");
1055
1090
  Intern_notify_writable = rb_intern ("notify_writable");
1056
1091
  Intern_proxy_target_unbound = rb_intern ("proxy_target_unbound");
1092
+ Intern_proxy_completed = rb_intern ("proxy_completed");
1093
+ Intern_connection_completed = rb_intern ("connection_completed");
1057
1094
 
1058
1095
  // INCOMPLETE, we need to define class Connections inside module EventMachine
1059
1096
  // run_machine and run_machine_without_threads are now identical.
@@ -1097,7 +1134,7 @@ extern "C" void Init_rubyeventmachine()
1097
1134
  rb_define_module_function (EmModule, "resume_connection", (VALUE (*)(...))t_resume, 1);
1098
1135
  rb_define_module_function (EmModule, "connection_paused?", (VALUE (*)(...))t_paused_p, 1);
1099
1136
 
1100
- rb_define_module_function (EmModule, "start_proxy", (VALUE (*)(...))t_start_proxy, 3);
1137
+ rb_define_module_function (EmModule, "start_proxy", (VALUE (*)(...))t_start_proxy, 4);
1101
1138
  rb_define_module_function (EmModule, "stop_proxy", (VALUE (*)(...))t_stop_proxy, 1);
1102
1139
 
1103
1140
  rb_define_module_function (EmModule, "watch_filename", (VALUE (*)(...))t_watch_filename, 1);
@@ -1123,9 +1160,6 @@ extern "C" void Init_rubyeventmachine()
1123
1160
  rb_define_module_function (EmModule, "get_heartbeat_interval", (VALUE(*)(...))t_get_heartbeat_interval, 0);
1124
1161
  rb_define_module_function (EmModule, "set_heartbeat_interval", (VALUE(*)(...))t_set_heartbeat_interval, 1);
1125
1162
 
1126
- // Provisional:
1127
- rb_define_module_function (EmModule, "_write_file", (VALUE(*)(...))t__write_file, 1);
1128
-
1129
1163
  rb_define_module_function (EmModule, "get_peername", (VALUE(*)(...))t_get_peername, 1);
1130
1164
  rb_define_module_function (EmModule, "get_sockname", (VALUE(*)(...))t_get_sockname, 1);
1131
1165
  rb_define_module_function (EmModule, "get_subprocess_pid", (VALUE(*)(...))t_get_subprocess_pid, 1);