eventmachine 0.12.8-java → 0.12.10-java

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (66) hide show
  1. data/.gitignore +2 -1
  2. data/Rakefile +155 -45
  3. data/eventmachine.gemspec +4 -5
  4. data/ext/binder.cpp +13 -14
  5. data/ext/binder.h +5 -7
  6. data/ext/cmain.cpp +184 -42
  7. data/ext/cplusplus.cpp +20 -20
  8. data/ext/ed.cpp +242 -81
  9. data/ext/ed.h +39 -22
  10. data/ext/em.cpp +127 -108
  11. data/ext/em.h +27 -18
  12. data/ext/emwin.cpp +3 -3
  13. data/ext/eventmachine.h +49 -38
  14. data/ext/eventmachine_cpp.h +4 -4
  15. data/ext/extconf.rb +28 -13
  16. data/ext/fastfilereader/extconf.rb +11 -5
  17. data/ext/project.h +12 -1
  18. data/ext/rubymain.cpp +222 -103
  19. data/ext/ssl.cpp +3 -3
  20. data/ext/ssl.h +2 -2
  21. data/java/src/com/rubyeventmachine/EmReactor.java +396 -249
  22. data/java/src/com/rubyeventmachine/EventableChannel.java +16 -4
  23. data/java/src/com/rubyeventmachine/EventableDatagramChannel.java +23 -5
  24. data/java/src/com/rubyeventmachine/EventableSocketChannel.java +181 -61
  25. data/java/src/com/rubyeventmachine/{Application.java → application/Application.java} +25 -31
  26. data/java/src/com/rubyeventmachine/{Connection.java → application/Connection.java} +2 -2
  27. data/java/src/com/rubyeventmachine/{ConnectionFactory.java → application/ConnectionFactory.java} +1 -1
  28. data/java/src/com/rubyeventmachine/{DefaultConnectionFactory.java → application/DefaultConnectionFactory.java} +2 -2
  29. data/java/src/com/rubyeventmachine/{PeriodicTimer.java → application/PeriodicTimer.java} +1 -1
  30. data/java/src/com/rubyeventmachine/{Timer.java → application/Timer.java} +1 -1
  31. data/java/src/com/rubyeventmachine/tests/ApplicationTest.java +1 -0
  32. data/java/src/com/rubyeventmachine/tests/ConnectTest.java +4 -2
  33. data/java/src/com/rubyeventmachine/tests/TestDatagrams.java +1 -1
  34. data/java/src/com/rubyeventmachine/tests/TestServers.java +1 -0
  35. data/java/src/com/rubyeventmachine/tests/TestTimers.java +1 -0
  36. data/lib/em/connection.rb +71 -12
  37. data/lib/em/deferrable.rb +5 -0
  38. data/lib/em/protocols.rb +1 -0
  39. data/lib/em/protocols/httpclient2.rb +8 -0
  40. data/lib/em/protocols/line_and_text.rb +0 -1
  41. data/lib/em/protocols/linetext2.rb +1 -0
  42. data/lib/em/protocols/object_protocol.rb +8 -2
  43. data/lib/em/protocols/smtpclient.rb +42 -16
  44. data/lib/em/protocols/socks4.rb +66 -0
  45. data/lib/em/queue.rb +1 -1
  46. data/lib/em/timers.rb +2 -1
  47. data/lib/em/version.rb +1 -1
  48. data/lib/eventmachine.rb +125 -169
  49. data/lib/jeventmachine.rb +124 -9
  50. data/tasks/{cpp.rake → cpp.rake_example} +0 -0
  51. data/tests/test_attach.rb +29 -4
  52. data/tests/test_basic.rb +1 -2
  53. data/tests/test_connection_count.rb +10 -20
  54. data/tests/test_epoll.rb +0 -2
  55. data/tests/test_get_sock_opt.rb +30 -0
  56. data/tests/test_httpclient2.rb +3 -3
  57. data/tests/test_inactivity_timeout.rb +21 -1
  58. data/tests/test_ltp.rb +0 -6
  59. data/tests/test_next_tick.rb +0 -2
  60. data/tests/test_pause.rb +70 -0
  61. data/tests/test_pending_connect_timeout.rb +48 -0
  62. data/tests/test_ssl_args.rb +16 -5
  63. data/tests/test_timers.rb +22 -1
  64. metadata +59 -52
  65. data/tasks/project.rake +0 -79
  66. data/tasks/tests.rake +0 -193
data/ext/em.h CHANGED
@@ -34,8 +34,16 @@ See the file COPYING for complete licensing information.
34
34
  #include <ruby.h>
35
35
  #define EmSelect rb_thread_select
36
36
 
37
- #ifdef HAVE_RBTRAP
37
+ #if defined(HAVE_RBTRAP)
38
38
  #include <rubysig.h>
39
+ #elif defined(HAVE_RB_THREAD_CHECK_INTS)
40
+ extern "C" {
41
+ void rb_enable_interrupt(void);
42
+ void rb_disable_interrupt(void);
43
+ }
44
+
45
+ #define TRAP_BEG rb_enable_interrupt()
46
+ #define TRAP_END do { rb_disable_interrupt(); rb_thread_check_ints(); } while(0)
39
47
  #else
40
48
  #define TRAP_BEG
41
49
  #define TRAP_END
@@ -74,28 +82,28 @@ class EventMachine_t
74
82
  static void SetMaxTimerCount (int);
75
83
 
76
84
  public:
77
- EventMachine_t (void(*event_callback)(const char*, int, const char*, int));
85
+ EventMachine_t (void(*event_callback)(const unsigned long, int, const char*, const unsigned long));
78
86
  virtual ~EventMachine_t();
79
87
 
80
88
  void Run();
81
89
  void ScheduleHalt();
82
90
  void SignalLoopBreaker();
83
- const char *InstallOneshotTimer (int);
84
- const char *ConnectToServer (const char *, int, const char *, int);
85
- const char *ConnectToUnixServer (const char *);
86
-
87
- const char *CreateTcpServer (const char *, int);
88
- const char *OpenDatagramSocket (const char *, int);
89
- const char *CreateUnixDomainServer (const char*);
90
- const char *_OpenFileForWriting (const char*);
91
- const char *OpenKeyboard();
91
+ const unsigned long InstallOneshotTimer (int);
92
+ const unsigned long ConnectToServer (const char *, int, const char *, int);
93
+ const unsigned long ConnectToUnixServer (const char *);
94
+
95
+ const unsigned long CreateTcpServer (const char *, int);
96
+ const unsigned long OpenDatagramSocket (const char *, int);
97
+ const unsigned long CreateUnixDomainServer (const char*);
98
+ const unsigned long _OpenFileForWriting (const char*);
99
+ const unsigned long OpenKeyboard();
92
100
  //const char *Popen (const char*, const char*);
93
- const char *Socketpair (char* const*);
101
+ const unsigned long Socketpair (char* const*);
94
102
 
95
103
  void Add (EventableDescriptor*);
96
104
  void Modify (EventableDescriptor*);
97
105
 
98
- const char *AttachFD (int, bool, bool);
106
+ const unsigned long AttachFD (int, bool);
99
107
  int DetachFD (EventableDescriptor*);
100
108
 
101
109
  void ArmKqueueWriter (EventableDescriptor*);
@@ -112,18 +120,18 @@ class EventMachine_t
112
120
  float GetHeartbeatInterval();
113
121
  int SetHeartbeatInterval(float);
114
122
 
115
- const char *WatchFile (const char*);
123
+ const unsigned long WatchFile (const char*);
116
124
  void UnwatchFile (int);
117
- void UnwatchFile (const char*);
125
+ void UnwatchFile (const unsigned long);
118
126
 
119
127
  #ifdef HAVE_KQUEUE
120
128
  void _HandleKqueueFileEvent (struct kevent*);
121
129
  void _RegisterKqueueFileEvent(int);
122
130
  #endif
123
131
 
124
- const char *WatchPid (int);
132
+ const unsigned long WatchPid (int);
125
133
  void UnwatchPid (int);
126
- void UnwatchPid (const char *);
134
+ void UnwatchPid (const unsigned long);
127
135
 
128
136
  #ifdef HAVE_KQUEUE
129
137
  void _HandleKqueuePidEvent (struct kevent*);
@@ -160,7 +168,7 @@ class EventMachine_t
160
168
  MaxEvents = 4096
161
169
  };
162
170
  int HeartbeatInterval;
163
- void (*EventCallback)(const char*, int, const char*, int);
171
+ void (*EventCallback)(const unsigned long, int, const char*, const unsigned long);
164
172
 
165
173
  class Timer_t: public Bindable_t {
166
174
  };
@@ -212,6 +220,7 @@ struct SelectData_t
212
220
  int maxsocket;
213
221
  fd_set fdreads;
214
222
  fd_set fdwrites;
223
+ fd_set fderrors;
215
224
  timeval tv;
216
225
  int nSockets;
217
226
  };
@@ -138,7 +138,7 @@ bool EventMachine_t::_RunTimers()
138
138
  if (i->first > gCurrentLoopTime)
139
139
  break;
140
140
  if (EventCallback)
141
- (*EventCallback) ("", EM_TIMER_FIRED, i->second.GetBinding().c_str(), i->second.GetBinding().length());
141
+ (*EventCallback) (NULL, EM_TIMER_FIRED, NULL, i->second.GetBinding());
142
142
  Timers.erase (i);
143
143
  }
144
144
  return true;
@@ -158,7 +158,7 @@ const char *EventMachine_t::InstallOneshotTimer (int seconds)
158
158
 
159
159
  Timer_t t;
160
160
  Timers.insert (make_pair (time(NULL) + seconds, t));
161
- return t.GetBinding().c_str();
161
+ return t.GetBinding();
162
162
  }
163
163
 
164
164
 
@@ -230,7 +230,7 @@ const char *EventMachine_t::CreateTcpServer (const char *server, int port)
230
230
  if (!ad)
231
231
  throw std::runtime_error ("unable to allocate acceptor");
232
232
  Add (ad);
233
- output_binding = ad->GetBinding().c_str();
233
+ output_binding = ad->GetBinding();
234
234
 
235
235
  CreateIoCompletionPort ((HANDLE)sd_accept, Iocp, NULL, 0);
236
236
  SOCKET sd = socket (AF_INET, SOCK_STREAM, 0);
@@ -39,43 +39,54 @@ extern "C" {
39
39
 
40
40
  };
41
41
 
42
- void evma_initialize_library (void(*)(const char*, int, const char*, int));
42
+ void evma_initialize_library (void(*)(const unsigned long, int, const char*, const unsigned long));
43
43
  void evma_run_machine();
44
44
  void evma_release_library();
45
- const char *evma_install_oneshot_timer (int seconds);
46
- const char *evma_connect_to_server (const char *bind_addr, int bind_port, const char *server, int port);
47
- const char *evma_connect_to_unix_server (const char *server);
48
-
49
- const char *evma_attach_fd (int file_descriptor, int read_mode, int write_mode);
50
- int evma_detach_fd (const char *binding);
51
-
52
- void evma_stop_tcp_server (const char *signature);
53
- const char *evma_create_tcp_server (const char *address, int port);
54
- const char *evma_create_unix_domain_server (const char *filename);
55
- const char *evma_open_datagram_socket (const char *server, int port);
56
- const char *evma_open_keyboard();
57
- void evma_set_tls_parms (const char *binding, const char *privatekey_filename, const char *certchain_filenane, int verify_peer);
58
- void evma_start_tls (const char *binding);
45
+ const unsigned long evma_install_oneshot_timer (int seconds);
46
+ const unsigned long evma_connect_to_server (const char *bind_addr, int bind_port, const char *server, int port);
47
+ const unsigned long evma_connect_to_unix_server (const char *server);
48
+
49
+ const unsigned long evma_attach_fd (int file_descriptor, int watch_mode);
50
+ int evma_detach_fd (const unsigned long binding);
51
+ int evma_get_file_descriptor (const unsigned long binding);
52
+ int evma_is_notify_readable (const unsigned long binding);
53
+ void evma_set_notify_readable (const unsigned long binding, int mode);
54
+ int evma_is_notify_writable (const unsigned long binding);
55
+ void evma_set_notify_writable (const unsigned long binding, int mode);
56
+
57
+ int evma_pause(const unsigned long binding);
58
+ int evma_is_paused(const unsigned long binding);
59
+ int evma_resume(const unsigned long binding);
60
+
61
+ void evma_stop_tcp_server (const unsigned long signature);
62
+ const unsigned long evma_create_tcp_server (const char *address, int port);
63
+ const unsigned long evma_create_unix_domain_server (const char *filename);
64
+ const unsigned long evma_open_datagram_socket (const char *server, int port);
65
+ const unsigned long evma_open_keyboard();
66
+ void evma_set_tls_parms (const unsigned long binding, const char *privatekey_filename, const char *certchain_filenane, int verify_peer);
67
+ void evma_start_tls (const unsigned long binding);
59
68
 
60
69
  #ifdef WITH_SSL
61
- X509 *evma_get_peer_cert (const char *binding);
62
- void evma_accept_ssl_peer (const char *binding);
70
+ X509 *evma_get_peer_cert (const unsigned long binding);
71
+ void evma_accept_ssl_peer (const unsigned long binding);
63
72
  #endif
64
73
 
65
- int evma_get_peername (const char *binding, struct sockaddr*);
66
- int evma_get_sockname (const char *binding, struct sockaddr*);
67
- int evma_get_subprocess_pid (const char *binding, pid_t*);
68
- int evma_get_subprocess_status (const char *binding, int*);
74
+ int evma_get_peername (const unsigned long binding, struct sockaddr*);
75
+ int evma_get_sockname (const unsigned long binding, struct sockaddr*);
76
+ int evma_get_subprocess_pid (const unsigned long binding, pid_t*);
77
+ int evma_get_subprocess_status (const unsigned long binding, int*);
69
78
  int evma_get_connection_count();
70
- int evma_send_data_to_connection (const char *binding, const char *data, int data_length);
71
- int evma_send_datagram (const char *binding, const char *data, int data_length, const char *address, int port);
72
- float evma_get_comm_inactivity_timeout (const char *binding);
73
- int evma_set_comm_inactivity_timeout (const char *binding, float value);
74
- int evma_get_outbound_data_size (const char *binding);
75
- int evma_send_file_data_to_connection (const char *binding, const char *filename);
76
-
77
- void evma_close_connection (const char *binding, int after_writing);
78
- int evma_report_connection_error_status (const char *binding);
79
+ int evma_send_data_to_connection (const unsigned long binding, const char *data, int data_length);
80
+ int evma_send_datagram (const unsigned long binding, const char *data, int data_length, const char *address, int port);
81
+ float evma_get_comm_inactivity_timeout (const unsigned long binding);
82
+ int evma_set_comm_inactivity_timeout (const unsigned long binding, float value);
83
+ float evma_get_pending_connect_timeout (const unsigned long binding);
84
+ int evma_set_pending_connect_timeout (const unsigned long binding, float value);
85
+ int evma_get_outbound_data_size (const unsigned long binding);
86
+ int evma_send_file_data_to_connection (const unsigned long binding, const char *filename);
87
+
88
+ void evma_close_connection (const unsigned long binding, int after_writing);
89
+ int evma_report_connection_error_status (const unsigned long binding);
79
90
  void evma_signal_loopbreak();
80
91
  void evma_set_timer_quantum (int);
81
92
  int evma_get_max_timer_count();
@@ -85,17 +96,17 @@ extern "C" {
85
96
  float evma_get_heartbeat_interval();
86
97
  int evma_set_heartbeat_interval(float);
87
98
 
88
- const char *evma__write_file (const char *filename);
89
- const char *evma_popen (char * const*cmd_strings);
99
+ const unsigned long evma__write_file (const char *filename);
100
+ const unsigned long evma_popen (char * const*cmd_strings);
90
101
 
91
- const char *evma_watch_filename (const char *fname);
92
- void evma_unwatch_filename (const char *sig);
102
+ const unsigned long evma_watch_filename (const char *fname);
103
+ void evma_unwatch_filename (const unsigned long);
93
104
 
94
- const char *evma_watch_pid (int);
95
- void evma_unwatch_pid (const char *sig);
105
+ const unsigned long evma_watch_pid (int);
106
+ void evma_unwatch_pid (const unsigned long);
96
107
 
97
- void evma_start_proxy(const char*, const char*);
98
- void evma_stop_proxy(const char*);
108
+ void evma_start_proxy(const unsigned long, const unsigned long, const unsigned long);
109
+ void evma_stop_proxy(const unsigned long);
99
110
 
100
111
  int evma_set_rlimit_nofile (int n_files);
101
112
 
@@ -26,7 +26,7 @@ See the file COPYING for complete licensing information.
26
26
 
27
27
  namespace EM {
28
28
 
29
- void Callback (const char *sig, int event, const char *data, int length);
29
+ void Callback (const unsigned long sig, int event, const char *data, const unsigned long length);
30
30
  void Run (void(*)(void));
31
31
  void AddTimer (int, void(*)());
32
32
  void StopReactor();
@@ -40,12 +40,12 @@ namespace EM {
40
40
  Eventable() {}
41
41
  virtual ~Eventable() {}
42
42
 
43
- std::string Signature;
43
+ unsigned long Signature;
44
44
 
45
45
  // Called by the framework
46
46
  virtual void ReceiveData (const char *data, int length) {}
47
47
  virtual void ConnectionCompleted() {}
48
- virtual void Accept (const char*) {}
48
+ virtual void Accept (const unsigned long) {}
49
49
  virtual void Unbind() {}
50
50
  virtual void PostInit() {}
51
51
  virtual void SslHandshakeCompleted() {}
@@ -81,7 +81,7 @@ namespace EM {
81
81
  virtual ~Acceptor() {}
82
82
 
83
83
  void Start (const char*, int);
84
- void Accept (const char*);
84
+ void Accept (const unsigned long);
85
85
 
86
86
  virtual Connection *MakeConnection() {return new Connection();}
87
87
  };
@@ -18,6 +18,8 @@ add_define "HAVE_TBR" if have_func('rb_thread_blocking_region')# and have_macro(
18
18
  add_define "HAVE_INOTIFY" if inotify = have_func('inotify_init', 'sys/inotify.h')
19
19
  add_define "HAVE_OLD_INOTIFY" if !inotify && have_macro('__NR_inotify_init', 'sys/syscall.h')
20
20
  add_define 'HAVE_WRITEV' if have_func('writev', 'sys/uio.h')
21
+ have_func('rb_thread_check_ints')
22
+ have_func('rb_time_new')
21
23
 
22
24
  # Minor platform details between *nix and Windows:
23
25
 
@@ -48,9 +50,8 @@ when /mswin32/, /mingw32/, /bccwin32/
48
50
  end
49
51
 
50
52
  when /solaris/
51
- check_libs(%w[nsl socket], true)
52
-
53
53
  add_define 'OS_SOLARIS8'
54
+ check_libs(%w[nsl socket], true)
54
55
 
55
56
  # Patch by Tim Pease, fixes SUNWspro compile problems.
56
57
  if CONFIG['CC'] == 'cc'
@@ -67,31 +68,36 @@ when /openbsd/
67
68
  # OpenBSD branch contributed by Guillaume Sellier.
68
69
 
69
70
  # on Unix we need a g++ link, not gcc. On OpenBSD, linking against libstdc++ have to be explicitly done for shared libs
70
- CONFIG['LDSHARED'] = "$(CXX) -shared -lstdc++"
71
+ CONFIG['LDSHARED'] = "$(CXX) -shared -lstdc++ -fPIC"
72
+ CONFIG['LDSHAREDXX'] = "$(CXX) -shared -lstdc++ -fPIC"
71
73
 
72
74
  when /darwin/
73
-
74
75
  # on Unix we need a g++ link, not gcc.
75
76
  # Ff line contributed by Daniel Harple.
76
77
  CONFIG['LDSHARED'] = "$(CXX) " + CONFIG['LDSHARED'].split[1..-1].join(' ')
77
78
 
78
79
  when /linux/
80
+ add_define 'HAVE_EPOLL' if have_func('epoll_create', 'sys/epoll.h')
79
81
 
80
82
  # Original epoll test is inadequate because 2.4 kernels have the header
81
83
  # but not the code.
82
84
  # add_define 'HAVE_EPOLL' if have_header('sys/epoll.h')
83
- if have_header('sys/epoll.h')
84
- File.open("hasEpollTest.c", "w") {|f|
85
- f.puts "#include <sys/epoll.h>"
86
- f.puts "int main() { epoll_create(1024); return 0;}"
87
- }
88
- (e = system( "gcc hasEpollTest.c -o hasEpollTest " )) and (e = $?.to_i)
89
- `rm -f hasEpollTest.c hasEpollTest`
90
- add_define 'HAVE_EPOLL' if e == 0
91
- end
85
+ # if have_header('sys/epoll.h')
86
+ # File.open("hasEpollTest.c", "w") {|f|
87
+ # f.puts "#include <sys/epoll.h>"
88
+ # f.puts "int main() { epoll_create(1024); return 0;}"
89
+ # }
90
+ # (e = system( "gcc hasEpollTest.c -o hasEpollTest " )) and (e = $?.to_i)
91
+ # `rm -f hasEpollTest.c hasEpollTest`
92
+ # add_define 'HAVE_EPOLL' if e == 0
93
+ # end
92
94
 
93
95
  # on Unix we need a g++ link, not gcc.
94
96
  CONFIG['LDSHARED'] = "$(CXX) -shared"
97
+
98
+ when /aix/
99
+ CONFIG['LDSHARED'] = "$(CXX) -shared -Wl,-G -Wl,-brtl"
100
+
95
101
  else
96
102
  # on Unix we need a g++ link, not gcc.
97
103
  CONFIG['LDSHARED'] = "$(CXX) -shared"
@@ -130,4 +136,13 @@ else
130
136
  add_define "WITHOUT_SSL"
131
137
  end
132
138
 
139
+ # solaris c++ compiler doesn't have make_pair()
140
+ TRY_LINK.sub!('$(CC)', '$(CXX)')
141
+ add_define 'HAVE_MAKE_PAIR' if try_link(<<SRC, '-lstdc++')
142
+ #include <utility>
143
+ using namespace std;
144
+ int main(){ pair<int,int> tuple = make_pair(1,2); }
145
+ SRC
146
+ TRY_LINK.sub!('$(CXX)', '$(CC)')
147
+
133
148
  create_makefile "rubyeventmachine"
@@ -26,7 +26,7 @@ else
26
26
  add_define 'OS_UNIX'
27
27
  end
28
28
 
29
-
29
+ # Main platform invariances:
30
30
 
31
31
  case RUBY_PLATFORM
32
32
  when /mswin32/, /mingw32/, /bccwin32/
@@ -41,9 +41,8 @@ when /mswin32/, /mingw32/, /bccwin32/
41
41
  end
42
42
 
43
43
  when /solaris/
44
- check_libs(%w[nsl socket], true)
45
-
46
44
  add_define 'OS_SOLARIS8'
45
+ check_libs(%w[nsl socket], true)
47
46
 
48
47
  # Patch by Tim Pease, fixes SUNWspro compile problems.
49
48
  if CONFIG['CC'] == 'cc'
@@ -55,20 +54,27 @@ when /solaris/
55
54
  # on Unix we need a g++ link, not gcc.
56
55
  CONFIG['LDSHARED'] = "$(CXX) -shared"
57
56
  end
57
+
58
58
  when /openbsd/
59
59
  # OpenBSD branch contributed by Guillaume Sellier.
60
60
 
61
61
  # on Unix we need a g++ link, not gcc. On OpenBSD, linking against libstdc++ have to be explicitly done for shared libs
62
- CONFIG['LDSHARED'] = "$(CXX) -shared -lstdc++"
62
+ CONFIG['LDSHARED'] = "$(CXX) -shared -lstdc++ -fPIC"
63
+ CONFIG['LDSHAREDXX'] = "$(CXX) -shared -lstdc++ -fPIC"
64
+
63
65
  when /darwin/
64
66
  # on Unix we need a g++ link, not gcc.
65
67
  # Ff line contributed by Daniel Harple.
66
68
  CONFIG['LDSHARED'] = "$(CXX) " + CONFIG['LDSHARED'].split[1..-1].join(' ')
67
69
 
68
70
  when /linux/
69
-
70
71
  # on Unix we need a g++ link, not gcc.
71
72
  CONFIG['LDSHARED'] = "$(CXX) -shared"
73
+
74
+ when /aix/
75
+ # on Unix we need a g++ link, not gcc.
76
+ CONFIG['LDSHARED'] = "$(CXX) -shared -Wl,-G"
77
+
72
78
  else
73
79
  # on Unix we need a g++ link, not gcc.
74
80
  CONFIG['LDSHARED'] = "$(CXX) -shared"
@@ -69,11 +69,21 @@ typedef int SOCKET;
69
69
  #ifndef INADDR_NONE
70
70
  #define INADDR_NONE ((unsigned long)-1)
71
71
  #endif
72
+ #endif /* OS_SOLARIS8 */
73
+
74
+ #ifdef _AIX
75
+ #include <strings.h>
76
+ #ifndef AF_LOCAL
77
+ #define AF_LOCAL AF_UNIX
72
78
  #endif
73
- #endif
79
+ #endif /* _AIX */
74
80
 
81
+ #endif /* OS_UNIX */
75
82
 
76
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
+
77
87
  #define WIN32_LEAN_AND_MEAN
78
88
  #include <windows.h>
79
89
  #include <winsock2.h>
@@ -81,6 +91,7 @@ typedef int SOCKET;
81
91
  #include <rpc.h>
82
92
  #include <fcntl.h>
83
93
  #include <assert.h>
94
+
84
95
  typedef int socklen_t;
85
96
  typedef int pid_t;
86
97
  #endif
@@ -32,8 +32,10 @@ Statics
32
32
  static VALUE EmModule;
33
33
  static VALUE EmConnection;
34
34
 
35
+ static VALUE EM_eConnectionError;
35
36
  static VALUE EM_eUnknownTimerFired;
36
37
  static VALUE EM_eConnectionNotBound;
38
+ static VALUE EM_eUnsupported;
37
39
 
38
40
  static VALUE Intern_at_signature;
39
41
  static VALUE Intern_at_timers;
@@ -53,10 +55,10 @@ static VALUE Intern_proxy_target_unbound;
53
55
  static VALUE rb_cProcStatus;
54
56
 
55
57
  struct em_event {
56
- const char *a1;
58
+ unsigned long a1;
57
59
  int a2;
58
60
  const char *a3;
59
- int a4;
61
+ unsigned long a4;
60
62
  };
61
63
 
62
64
  /****************
@@ -65,30 +67,30 @@ t_event_callback
65
67
 
66
68
  static void event_callback (struct em_event* e)
67
69
  {
68
- const char *a1 = e->a1;
70
+ const unsigned long a1 = e->a1;
69
71
  int a2 = e->a2;
70
72
  const char *a3 = e->a3;
71
- int a4 = e->a4;
73
+ const unsigned long a4 = e->a4;
72
74
 
73
75
  if (a2 == EM_CONNECTION_READ) {
74
76
  VALUE t = rb_ivar_get (EmModule, Intern_at_conns);
75
- VALUE q = rb_hash_aref (t, rb_str_new2(a1));
77
+ VALUE q = rb_hash_aref (t, ULONG2NUM (a1));
76
78
  if (q == Qnil)
77
- rb_raise (EM_eConnectionNotBound, "received %d bytes of data for unknown signature: %s", a4, a1);
79
+ rb_raise (EM_eConnectionNotBound, "received %lu bytes of data for unknown signature: %lu", a4, a1);
78
80
  rb_funcall (q, Intern_receive_data, 1, rb_str_new (a3, a4));
79
81
  }
80
82
  else if (a2 == EM_CONNECTION_NOTIFY_READABLE) {
81
83
  VALUE t = rb_ivar_get (EmModule, Intern_at_conns);
82
- VALUE q = rb_hash_aref (t, rb_str_new2(a1));
84
+ VALUE q = rb_hash_aref (t, ULONG2NUM (a1));
83
85
  if (q == Qnil)
84
- rb_raise (EM_eConnectionNotBound, "unknown connection: %s", a1);
86
+ rb_raise (EM_eConnectionNotBound, "unknown connection: %lu", a1);
85
87
  rb_funcall (q, Intern_notify_readable, 0);
86
88
  }
87
89
  else if (a2 == EM_CONNECTION_NOTIFY_WRITABLE) {
88
90
  VALUE t = rb_ivar_get (EmModule, Intern_at_conns);
89
- VALUE q = rb_hash_aref (t, rb_str_new2(a1));
91
+ VALUE q = rb_hash_aref (t, ULONG2NUM (a1));
90
92
  if (q == Qnil)
91
- rb_raise (EM_eConnectionNotBound, "unknown connection: %s", a1);
93
+ rb_raise (EM_eConnectionNotBound, "unknown connection: %lu", a1);
92
94
  rb_funcall (q, Intern_notify_writable, 0);
93
95
  }
94
96
  else if (a2 == EM_LOOPBREAK_SIGNAL) {
@@ -96,9 +98,9 @@ static void event_callback (struct em_event* e)
96
98
  }
97
99
  else if (a2 == EM_TIMER_FIRED) {
98
100
  VALUE t = rb_ivar_get (EmModule, Intern_at_timers);
99
- VALUE q = rb_funcall (t, Intern_delete, 1, rb_str_new(a3, a4));
101
+ VALUE q = rb_funcall (t, Intern_delete, 1, ULONG2NUM (a4));
100
102
  if (q == Qnil) {
101
- rb_raise (EM_eUnknownTimerFired, "no such timer: %s", a1);
103
+ rb_raise (EM_eUnknownTimerFired, "no such timer: %lu", a4);
102
104
  } else if (q == Qfalse) {
103
105
  /* Timer Canceled */
104
106
  } else {
@@ -108,16 +110,16 @@ static void event_callback (struct em_event* e)
108
110
  #ifdef WITH_SSL
109
111
  else if (a2 == EM_SSL_HANDSHAKE_COMPLETED) {
110
112
  VALUE t = rb_ivar_get (EmModule, Intern_at_conns);
111
- VALUE q = rb_hash_aref (t, rb_str_new2(a1));
113
+ VALUE q = rb_hash_aref (t, ULONG2NUM (a1));
112
114
  if (q == Qnil)
113
- rb_raise (EM_eConnectionNotBound, "unknown connection: %s", a1);
115
+ rb_raise (EM_eConnectionNotBound, "unknown connection: %lu", a1);
114
116
  rb_funcall (q, Intern_ssl_handshake_completed, 0);
115
117
  }
116
118
  else if (a2 == EM_SSL_VERIFY) {
117
119
  VALUE t = rb_ivar_get (EmModule, Intern_at_conns);
118
- VALUE q = rb_hash_aref (t, rb_str_new2(a1));
120
+ VALUE q = rb_hash_aref (t, ULONG2NUM (a1));
119
121
  if (q == Qnil)
120
- rb_raise (EM_eConnectionNotBound, "unknown connection: %s", a1);
122
+ rb_raise (EM_eConnectionNotBound, "unknown connection: %lu", a1);
121
123
  VALUE r = rb_funcall (q, Intern_ssl_verify_peer, 1, rb_str_new(a3, a4));
122
124
  if (RTEST(r))
123
125
  evma_accept_ssl_peer (a1);
@@ -125,13 +127,13 @@ static void event_callback (struct em_event* e)
125
127
  #endif
126
128
  else if (a2 == EM_PROXY_TARGET_UNBOUND) {
127
129
  VALUE t = rb_ivar_get (EmModule, Intern_at_conns);
128
- VALUE q = rb_hash_aref (t, rb_str_new2(a1));
130
+ VALUE q = rb_hash_aref (t, ULONG2NUM (a1));
129
131
  if (q == Qnil)
130
- rb_raise (EM_eConnectionNotBound, "unknown connection: %s", a1);
132
+ rb_raise (EM_eConnectionNotBound, "unknown connection: %lu", a1);
131
133
  rb_funcall (q, Intern_proxy_target_unbound, 0);
132
134
  }
133
135
  else
134
- rb_funcall (EmModule, Intern_event_callback, 3, rb_str_new2(a1), (a2 << 1) | 1, rb_str_new(a3,a4));
136
+ rb_funcall (EmModule, Intern_event_callback, 3, ULONG2NUM(a1), INT2FIX(a2), a3 ? rb_str_new(a3,a4) : ULONG2NUM(a4));
135
137
  }
136
138
 
137
139
  /*******************
@@ -148,7 +150,7 @@ static void event_error_handler(VALUE unused, VALUE err)
148
150
  event_callback_wrapper
149
151
  **********************/
150
152
 
151
- static void event_callback_wrapper (const char *a1, int a2, const char *a3, int a4)
153
+ static void event_callback_wrapper (const unsigned long a1, int a2, const char *a3, const unsigned long a4)
152
154
  {
153
155
  struct em_event e;
154
156
  e.a1 = a1;
@@ -191,10 +193,10 @@ t_add_oneshot_timer
191
193
 
192
194
  static VALUE t_add_oneshot_timer (VALUE self, VALUE interval)
193
195
  {
194
- const char *f = evma_install_oneshot_timer (FIX2INT (interval));
195
- if (!f || !*f)
196
- rb_raise (rb_eRuntimeError, "no timer");
197
- return rb_str_new2 (f);
196
+ const unsigned long f = evma_install_oneshot_timer (FIX2INT (interval));
197
+ if (!f)
198
+ rb_raise (rb_eRuntimeError, "ran out of timers; use #set_max_timers to increase limit");
199
+ return ULONG2NUM (f);
198
200
  }
199
201
 
200
202
 
@@ -204,10 +206,10 @@ t_start_server
204
206
 
205
207
  static VALUE t_start_server (VALUE self, VALUE server, VALUE port)
206
208
  {
207
- const char *f = evma_create_tcp_server (StringValuePtr(server), FIX2INT(port));
208
- if (!f || !*f)
209
+ const unsigned long f = evma_create_tcp_server (StringValuePtr(server), FIX2INT(port));
210
+ if (!f)
209
211
  rb_raise (rb_eRuntimeError, "no acceptor");
210
- return rb_str_new2 (f);
212
+ return ULONG2NUM (f);
211
213
  }
212
214
 
213
215
  /*************
@@ -216,7 +218,7 @@ t_stop_server
216
218
 
217
219
  static VALUE t_stop_server (VALUE self, VALUE signature)
218
220
  {
219
- evma_stop_tcp_server (StringValuePtr (signature));
221
+ evma_stop_tcp_server (NUM2ULONG (signature));
220
222
  return Qnil;
221
223
  }
222
224
 
@@ -227,10 +229,10 @@ t_start_unix_server
227
229
 
228
230
  static VALUE t_start_unix_server (VALUE self, VALUE filename)
229
231
  {
230
- const char *f = evma_create_unix_domain_server (StringValuePtr(filename));
231
- if (!f || !*f)
232
+ const unsigned long f = evma_create_unix_domain_server (StringValuePtr(filename));
233
+ if (!f)
232
234
  rb_raise (rb_eRuntimeError, "no unix-domain acceptor");
233
- return rb_str_new2 (f);
235
+ return ULONG2NUM (f);
234
236
  }
235
237
 
236
238
 
@@ -241,7 +243,7 @@ t_send_data
241
243
 
242
244
  static VALUE t_send_data (VALUE self, VALUE signature, VALUE data, VALUE data_length)
243
245
  {
244
- int b = evma_send_data_to_connection (StringValuePtr (signature), StringValuePtr (data), FIX2INT (data_length));
246
+ int b = evma_send_data_to_connection (NUM2ULONG (signature), StringValuePtr (data), FIX2INT (data_length));
245
247
  return INT2NUM (b);
246
248
  }
247
249
 
@@ -252,7 +254,7 @@ t_start_tls
252
254
 
253
255
  static VALUE t_start_tls (VALUE self, VALUE signature)
254
256
  {
255
- evma_start_tls (StringValuePtr (signature));
257
+ evma_start_tls (NUM2ULONG (signature));
256
258
  return Qnil;
257
259
  }
258
260
 
@@ -267,7 +269,7 @@ static VALUE t_set_tls_parms (VALUE self, VALUE signature, VALUE privkeyfile, VA
267
269
  * It's expected that the parameter list will grow as we add more supported features.
268
270
  * ALL of these parameters are optional, and can be specified as empty or NULL strings.
269
271
  */
270
- evma_set_tls_parms (StringValuePtr (signature), StringValuePtr (privkeyfile), StringValuePtr (certchainfile), (verify_peer == Qtrue ? 1 : 0));
272
+ evma_set_tls_parms (NUM2ULONG (signature), StringValuePtr (privkeyfile), StringValuePtr (certchainfile), (verify_peer == Qtrue ? 1 : 0));
271
273
  return Qnil;
272
274
  }
273
275
 
@@ -284,7 +286,7 @@ static VALUE t_get_peer_cert (VALUE self, VALUE signature)
284
286
  BUF_MEM *buf;
285
287
  BIO *out;
286
288
 
287
- cert = evma_get_peer_cert (StringValuePtr (signature));
289
+ cert = evma_get_peer_cert (NUM2ULONG (signature));
288
290
 
289
291
  if (cert != NULL) {
290
292
  out = BIO_new(BIO_s_mem());
@@ -306,7 +308,7 @@ t_get_peername
306
308
  static VALUE t_get_peername (VALUE self, VALUE signature)
307
309
  {
308
310
  struct sockaddr s;
309
- if (evma_get_peername (StringValuePtr (signature), &s)) {
311
+ if (evma_get_peername (NUM2ULONG (signature), &s)) {
310
312
  return rb_str_new ((const char*)&s, sizeof(s));
311
313
  }
312
314
 
@@ -320,7 +322,7 @@ t_get_sockname
320
322
  static VALUE t_get_sockname (VALUE self, VALUE signature)
321
323
  {
322
324
  struct sockaddr s;
323
- if (evma_get_sockname (StringValuePtr (signature), &s)) {
325
+ if (evma_get_sockname (NUM2ULONG (signature), &s)) {
324
326
  return rb_str_new ((const char*)&s, sizeof(s));
325
327
  }
326
328
 
@@ -334,7 +336,7 @@ t_get_subprocess_pid
334
336
  static VALUE t_get_subprocess_pid (VALUE self, VALUE signature)
335
337
  {
336
338
  pid_t pid;
337
- if (evma_get_subprocess_pid (StringValuePtr (signature), &pid)) {
339
+ if (evma_get_subprocess_pid (NUM2ULONG (signature), &pid)) {
338
340
  return INT2NUM (pid);
339
341
  }
340
342
 
@@ -352,8 +354,8 @@ static VALUE t_get_subprocess_status (VALUE self, VALUE signature)
352
354
  int status;
353
355
  pid_t pid;
354
356
 
355
- if (evma_get_subprocess_status (StringValuePtr (signature), &status)) {
356
- if (evma_get_subprocess_pid (StringValuePtr (signature), &pid)) {
357
+ if (evma_get_subprocess_status (NUM2ULONG (signature), &status)) {
358
+ if (evma_get_subprocess_pid (NUM2ULONG (signature), &pid)) {
357
359
  proc_status = rb_obj_alloc(rb_cProcStatus);
358
360
  rb_iv_set(proc_status, "status", INT2FIX(status));
359
361
  rb_iv_set(proc_status, "pid", INT2FIX(pid));
@@ -378,7 +380,7 @@ t_get_comm_inactivity_timeout
378
380
 
379
381
  static VALUE t_get_comm_inactivity_timeout (VALUE self, VALUE signature)
380
382
  {
381
- return rb_float_new(evma_get_comm_inactivity_timeout(StringValuePtr(signature)));
383
+ return rb_float_new(evma_get_comm_inactivity_timeout(NUM2ULONG (signature)));
382
384
  }
383
385
 
384
386
  /*****************************
@@ -388,11 +390,31 @@ t_set_comm_inactivity_timeout
388
390
  static VALUE t_set_comm_inactivity_timeout (VALUE self, VALUE signature, VALUE timeout)
389
391
  {
390
392
  float ti = RFLOAT_VALUE(timeout);
391
- if (evma_set_comm_inactivity_timeout (StringValuePtr (signature), ti));
393
+ if (evma_set_comm_inactivity_timeout (NUM2ULONG (signature), ti));
392
394
  return Qtrue;
393
395
  return Qfalse;
394
396
  }
395
397
 
398
+ /*****************************
399
+ t_get_pending_connect_timeout
400
+ *****************************/
401
+
402
+ static VALUE t_get_pending_connect_timeout (VALUE self, VALUE signature)
403
+ {
404
+ return rb_float_new(evma_get_pending_connect_timeout(NUM2ULONG (signature)));
405
+ }
406
+
407
+ /*****************************
408
+ t_set_pending_connect_timeout
409
+ *****************************/
410
+
411
+ static VALUE t_set_pending_connect_timeout (VALUE self, VALUE signature, VALUE timeout)
412
+ {
413
+ float ti = RFLOAT_VALUE(timeout);
414
+ if (evma_set_pending_connect_timeout (NUM2ULONG (signature), ti));
415
+ return Qtrue;
416
+ return Qfalse;
417
+ }
396
418
 
397
419
  /***************
398
420
  t_send_datagram
@@ -400,7 +422,7 @@ t_send_datagram
400
422
 
401
423
  static VALUE t_send_datagram (VALUE self, VALUE signature, VALUE data, VALUE data_length, VALUE address, VALUE port)
402
424
  {
403
- int b = evma_send_datagram (StringValuePtr (signature), StringValuePtr (data), FIX2INT (data_length), StringValuePtr(address), FIX2INT(port));
425
+ int b = evma_send_datagram (NUM2ULONG (signature), StringValuePtr (data), FIX2INT (data_length), StringValuePtr(address), FIX2INT(port));
404
426
  return INT2NUM (b);
405
427
  }
406
428
 
@@ -411,7 +433,7 @@ t_close_connection
411
433
 
412
434
  static VALUE t_close_connection (VALUE self, VALUE signature, VALUE after_writing)
413
435
  {
414
- evma_close_connection (StringValuePtr (signature), ((after_writing == Qtrue) ? 1 : 0));
436
+ evma_close_connection (NUM2ULONG (signature), ((after_writing == Qtrue) ? 1 : 0));
415
437
  return Qnil;
416
438
  }
417
439
 
@@ -421,7 +443,7 @@ t_report_connection_error_status
421
443
 
422
444
  static VALUE t_report_connection_error_status (VALUE self, VALUE signature)
423
445
  {
424
- int b = evma_report_connection_error_status (StringValuePtr (signature));
446
+ int b = evma_report_connection_error_status (NUM2ULONG (signature));
425
447
  return INT2NUM (b);
426
448
  }
427
449
 
@@ -437,10 +459,14 @@ static VALUE t_connect_server (VALUE self, VALUE server, VALUE port)
437
459
  // Specifically, if the value of port comes in as a string rather than an integer,
438
460
  // NUM2INT will throw a type error, but FIX2INT will generate garbage.
439
461
 
440
- const char *f = evma_connect_to_server (NULL, 0, StringValuePtr(server), NUM2INT(port));
441
- if (!f || !*f)
442
- rb_raise (rb_eRuntimeError, "no connection");
443
- return rb_str_new2 (f);
462
+ try {
463
+ const unsigned long f = evma_connect_to_server (NULL, 0, StringValuePtr(server), NUM2INT(port));
464
+ if (!f)
465
+ rb_raise (EM_eConnectionError, "no connection");
466
+ return ULONG2NUM (f);
467
+ } catch (std::runtime_error e) {
468
+ rb_raise (EM_eConnectionError, e.what());
469
+ }
444
470
  }
445
471
 
446
472
  /*********************
@@ -453,15 +479,14 @@ static VALUE t_bind_connect_server (VALUE self, VALUE bind_addr, VALUE bind_port
453
479
  // Specifically, if the value of port comes in as a string rather than an integer,
454
480
  // NUM2INT will throw a type error, but FIX2INT will generate garbage.
455
481
 
456
- const char *f;
457
482
  try {
458
- f = evma_connect_to_server (StringValuePtr(bind_addr), NUM2INT(bind_port), StringValuePtr(server), NUM2INT(port));
459
- if (!f || !*f)
460
- rb_raise (rb_eRuntimeError, "no connection");
483
+ const unsigned long f = evma_connect_to_server (StringValuePtr(bind_addr), NUM2INT(bind_port), StringValuePtr(server), NUM2INT(port));
484
+ if (!f)
485
+ rb_raise (EM_eConnectionError, "no connection");
486
+ return ULONG2NUM (f);
461
487
  } catch (std::runtime_error e) {
462
- rb_sys_fail(e.what());
488
+ rb_raise (EM_eConnectionError, e.what());
463
489
  }
464
- return rb_str_new2 (f);
465
490
  }
466
491
 
467
492
  /*********************
@@ -470,31 +495,113 @@ t_connect_unix_server
470
495
 
471
496
  static VALUE t_connect_unix_server (VALUE self, VALUE serversocket)
472
497
  {
473
- const char *f = evma_connect_to_unix_server (StringValuePtr(serversocket));
474
- if (!f || !*f)
498
+ const unsigned long f = evma_connect_to_unix_server (StringValuePtr(serversocket));
499
+ if (!f)
475
500
  rb_raise (rb_eRuntimeError, "no connection");
476
- return rb_str_new2 (f);
501
+ return ULONG2NUM (f);
477
502
  }
478
503
 
479
504
  /***********
480
505
  t_attach_fd
481
506
  ***********/
482
507
 
483
- static VALUE t_attach_fd (VALUE self, VALUE file_descriptor, VALUE read_mode, VALUE write_mode)
508
+ static VALUE t_attach_fd (VALUE self, VALUE file_descriptor, VALUE watch_mode)
484
509
  {
485
- const char *f = evma_attach_fd (NUM2INT(file_descriptor), (read_mode == Qtrue) ? 1 : 0, (write_mode == Qtrue) ? 1 : 0);
486
- if (!f || !*f)
510
+ const unsigned long f = evma_attach_fd (NUM2INT(file_descriptor), watch_mode == Qtrue);
511
+ if (!f)
487
512
  rb_raise (rb_eRuntimeError, "no connection");
488
- return rb_str_new2 (f);
513
+ return ULONG2NUM (f);
489
514
  }
490
515
 
491
516
  /***********
492
517
  t_detach_fd
493
518
  ***********/
494
519
 
495
- static VALUE t_detach_fd (VALUE self, VALUE signature)
520
+ static VALUE t_detach_fd (VALUE self, VALUE signature)
521
+ {
522
+ return INT2NUM(evma_detach_fd (NUM2ULONG (signature)));
523
+ }
524
+
525
+ /**************
526
+ t_get_sock_opt
527
+ **************/
528
+
529
+ static VALUE t_get_sock_opt (VALUE self, VALUE signature, VALUE lev, VALUE optname)
530
+ {
531
+ int fd = evma_get_file_descriptor (NUM2ULONG (signature));
532
+ int level = NUM2INT(lev), option = NUM2INT(optname);
533
+ socklen_t len = 128;
534
+ char buf[128];
535
+
536
+ if (getsockopt(fd, level, option, buf, &len) < 0)
537
+ rb_sys_fail("getsockopt");
538
+
539
+ return rb_str_new(buf, len);
540
+ }
541
+
542
+ /********************
543
+ t_is_notify_readable
544
+ ********************/
545
+
546
+ static VALUE t_is_notify_readable (VALUE self, VALUE signature)
547
+ {
548
+ return evma_is_notify_readable(NUM2ULONG (signature)) ? Qtrue : Qfalse;
549
+ }
550
+
551
+ /*********************
552
+ t_set_notify_readable
553
+ *********************/
554
+
555
+ static VALUE t_set_notify_readable (VALUE self, VALUE signature, VALUE mode)
496
556
  {
497
- return INT2NUM(evma_detach_fd (StringValuePtr(signature)));
557
+ evma_set_notify_readable(NUM2ULONG (signature), mode == Qtrue);
558
+ return Qnil;
559
+ }
560
+
561
+ /********************
562
+ t_is_notify_readable
563
+ ********************/
564
+
565
+ static VALUE t_is_notify_writable (VALUE self, VALUE signature)
566
+ {
567
+ return evma_is_notify_writable(NUM2ULONG (signature)) ? Qtrue : Qfalse;
568
+ }
569
+
570
+ /*********************
571
+ t_set_notify_writable
572
+ *********************/
573
+
574
+ static VALUE t_set_notify_writable (VALUE self, VALUE signature, VALUE mode)
575
+ {
576
+ evma_set_notify_writable(NUM2ULONG (signature), mode == Qtrue);
577
+ return Qnil;
578
+ }
579
+
580
+ /*******
581
+ t_pause
582
+ *******/
583
+
584
+ static VALUE t_pause (VALUE self, VALUE signature)
585
+ {
586
+ return evma_pause(NUM2ULONG (signature)) ? Qtrue : Qfalse;
587
+ }
588
+
589
+ /********
590
+ t_resume
591
+ ********/
592
+
593
+ static VALUE t_resume (VALUE self, VALUE signature)
594
+ {
595
+ return evma_resume(NUM2ULONG (signature)) ? Qtrue : Qfalse;
596
+ }
597
+
598
+ /**********
599
+ t_paused_p
600
+ **********/
601
+
602
+ static VALUE t_paused_p (VALUE self, VALUE signature)
603
+ {
604
+ return evma_is_paused(NUM2ULONG (signature)) ? Qtrue : Qfalse;
498
605
  }
499
606
 
500
607
  /*****************
@@ -503,10 +610,10 @@ t_open_udp_socket
503
610
 
504
611
  static VALUE t_open_udp_socket (VALUE self, VALUE server, VALUE port)
505
612
  {
506
- const char *f = evma_open_datagram_socket (StringValuePtr(server), FIX2INT(port));
507
- if (!f || !*f)
613
+ const unsigned long f = evma_open_datagram_socket (StringValuePtr(server), FIX2INT(port));
614
+ if (!f)
508
615
  rb_raise (rb_eRuntimeError, "no datagram socket");
509
- return rb_str_new2 (f);
616
+ return ULONG2NUM (f);
510
617
  }
511
618
 
512
619
 
@@ -600,10 +707,10 @@ t__write_file
600
707
 
601
708
  static VALUE t__write_file (VALUE self, VALUE filename)
602
709
  {
603
- const char *f = evma__write_file (StringValuePtr (filename));
604
- if (!f || !*f)
710
+ const unsigned long f = evma__write_file (StringValuePtr (filename));
711
+ if (!f)
605
712
  rb_raise (rb_eRuntimeError, "file not opened");
606
- return rb_str_new2 (f);
713
+ return ULONG2NUM (f);
607
714
  }
608
715
 
609
716
  /**************
@@ -628,15 +735,15 @@ static VALUE t_invoke_popen (VALUE self, VALUE cmd)
628
735
  }
629
736
  strings[len] = NULL;
630
737
 
631
- const char *f = evma_popen (strings);
632
- if (!f || !*f) {
738
+ const unsigned long f = evma_popen (strings);
739
+ if (!f) {
633
740
  char *err = strerror (errno);
634
741
  char buf[100];
635
742
  memset (buf, 0, sizeof(buf));
636
743
  snprintf (buf, sizeof(buf)-1, "no popen: %s", (err?err:"???"));
637
- rb_raise (rb_eRuntimeError, buf);
744
+ rb_raise (rb_eRuntimeError, "%s", buf);
638
745
  }
639
- return rb_str_new2 (f);
746
+ return ULONG2NUM (f);
640
747
  }
641
748
 
642
749
 
@@ -646,10 +753,10 @@ t_read_keyboard
646
753
 
647
754
  static VALUE t_read_keyboard (VALUE self)
648
755
  {
649
- const char *f = evma_open_keyboard();
650
- if (!f || !*f)
756
+ const unsigned long f = evma_open_keyboard();
757
+ if (!f)
651
758
  rb_raise (rb_eRuntimeError, "no keyboard reader");
652
- return rb_str_new2 (f);
759
+ return ULONG2NUM (f);
653
760
  }
654
761
 
655
762
 
@@ -660,7 +767,7 @@ t_watch_filename
660
767
  static VALUE t_watch_filename (VALUE self, VALUE fname)
661
768
  {
662
769
  try {
663
- return rb_str_new2(evma_watch_filename(StringValuePtr(fname)));
770
+ return ULONG2NUM(evma_watch_filename(StringValuePtr(fname)));
664
771
  } catch (std::runtime_error e) {
665
772
  rb_sys_fail(e.what());
666
773
  }
@@ -673,7 +780,7 @@ t_unwatch_filename
673
780
 
674
781
  static VALUE t_unwatch_filename (VALUE self, VALUE sig)
675
782
  {
676
- evma_unwatch_filename(StringValuePtr(sig));
783
+ evma_unwatch_filename(NUM2ULONG (sig));
677
784
  return Qnil;
678
785
  }
679
786
 
@@ -685,7 +792,7 @@ t_watch_pid
685
792
  static VALUE t_watch_pid (VALUE self, VALUE pid)
686
793
  {
687
794
  try {
688
- return rb_str_new2(evma_watch_pid(NUM2INT(pid)));
795
+ return ULONG2NUM(evma_watch_pid(NUM2INT(pid)));
689
796
  } catch (std::runtime_error e) {
690
797
  rb_sys_fail(e.what());
691
798
  }
@@ -698,7 +805,7 @@ t_unwatch_pid
698
805
 
699
806
  static VALUE t_unwatch_pid (VALUE self, VALUE sig)
700
807
  {
701
- evma_unwatch_pid(StringValuePtr(sig));
808
+ evma_unwatch_pid(NUM2ULONG (sig));
702
809
  return Qnil;
703
810
  }
704
811
 
@@ -722,9 +829,6 @@ t__epoll
722
829
 
723
830
  static VALUE t__epoll (VALUE self)
724
831
  {
725
- if (t__epoll_p(self) == Qfalse)
726
- return Qfalse;
727
-
728
832
  evma_set_epoll (1);
729
833
  return Qtrue;
730
834
  }
@@ -736,7 +840,7 @@ t__epoll_set
736
840
  static VALUE t__epoll_set (VALUE self, VALUE val)
737
841
  {
738
842
  if (t__epoll_p(self) == Qfalse)
739
- return Qfalse;
843
+ rb_raise (EM_eUnsupported, "epoll is not supported on this platform");
740
844
 
741
845
  evma_set_epoll (val == Qtrue ? 1 : 0);
742
846
  return val;
@@ -762,9 +866,6 @@ t__kqueue
762
866
 
763
867
  static VALUE t__kqueue (VALUE self)
764
868
  {
765
- if (t__kqueue_p(self) == Qfalse)
766
- return Qfalse;
767
-
768
869
  evma_set_kqueue (1);
769
870
  return Qtrue;
770
871
  }
@@ -776,7 +877,7 @@ t__kqueue_set
776
877
  static VALUE t__kqueue_set (VALUE self, VALUE val)
777
878
  {
778
879
  if (t__kqueue_p(self) == Qfalse)
779
- return Qfalse;
880
+ rb_raise (EM_eUnsupported, "kqueue is not supported on this platform");
780
881
 
781
882
  evma_set_kqueue (val == Qtrue ? 1 : 0);
782
883
  return val;
@@ -812,7 +913,7 @@ static VALUE t_send_file_data (VALUE self, VALUE signature, VALUE filename)
812
913
  * do this. For one thing it's ugly. For another, we can't be sure zero is never a real errno.
813
914
  */
814
915
 
815
- int b = evma_send_file_data_to_connection (StringValuePtr(signature), StringValuePtr(filename));
916
+ int b = evma_send_file_data_to_connection (NUM2ULONG (signature), StringValuePtr(filename));
816
917
  if (b == -1)
817
918
  rb_raise(rb_eRuntimeError, "File too large. send_file_data() supports files under 32k.");
818
919
  if (b > 0) {
@@ -821,7 +922,7 @@ static VALUE t_send_file_data (VALUE self, VALUE signature, VALUE filename)
821
922
  memset (buf, 0, sizeof(buf));
822
923
  snprintf (buf, sizeof(buf)-1, ": %s %s", StringValuePtr(filename),(err?err:"???"));
823
924
 
824
- rb_raise (rb_eIOError, buf);
925
+ rb_raise (rb_eIOError, "%s", buf);
825
926
  }
826
927
 
827
928
  return INT2NUM (0);
@@ -845,7 +946,7 @@ conn_get_outbound_data_size
845
946
  static VALUE conn_get_outbound_data_size (VALUE self)
846
947
  {
847
948
  VALUE sig = rb_ivar_get (self, Intern_at_signature);
848
- return INT2NUM (evma_get_outbound_data_size (StringValuePtr(sig)));
949
+ return INT2NUM (evma_get_outbound_data_size (NUM2ULONG (sig)));
849
950
  }
850
951
 
851
952
 
@@ -866,12 +967,17 @@ t_get_loop_time
866
967
 
867
968
  static VALUE t_get_loop_time (VALUE self)
868
969
  {
869
- VALUE cTime = rb_path2class("Time");
970
+ #ifndef HAVE_RB_TIME_NEW
971
+ static VALUE cTime = rb_path2class("Time");
972
+ static ID at = rb_intern("at");
973
+ #endif
974
+
870
975
  if (gCurrentLoopTime != 0) {
871
- return rb_funcall(cTime,
872
- rb_intern("at"),
873
- 1,
874
- INT2NUM(gCurrentLoopTime));
976
+ #ifndef HAVE_RB_TIME_NEW
977
+ return rb_funcall(cTime, at, 2, INT2NUM(gCurrentLoopTime / 1000000), INT2NUM(gCurrentLoopTime % 1000000));
978
+ #else
979
+ return rb_time_new(gCurrentLoopTime / 1000000, gCurrentLoopTime % 1000000);
980
+ #endif
875
981
  }
876
982
  return Qnil;
877
983
  }
@@ -881,9 +987,9 @@ static VALUE t_get_loop_time (VALUE self)
881
987
  t_start_proxy
882
988
  **************/
883
989
 
884
- static VALUE t_start_proxy (VALUE self, VALUE from, VALUE to)
990
+ static VALUE t_start_proxy (VALUE self, VALUE from, VALUE to, VALUE bufsize)
885
991
  {
886
- evma_start_proxy(StringValuePtr(from), StringValuePtr(to));
992
+ evma_start_proxy(NUM2ULONG (from), NUM2ULONG (to), NUM2ULONG(bufsize));
887
993
  return Qnil;
888
994
  }
889
995
 
@@ -894,7 +1000,7 @@ t_stop_proxy
894
1000
 
895
1001
  static VALUE t_stop_proxy (VALUE self, VALUE from)
896
1002
  {
897
- evma_stop_proxy(StringValuePtr(from));
1003
+ evma_stop_proxy(NUM2ULONG (from));
898
1004
  return Qnil;
899
1005
  }
900
1006
 
@@ -955,9 +1061,11 @@ extern "C" void Init_rubyeventmachine()
955
1061
  EmModule = rb_define_module ("EventMachine");
956
1062
  EmConnection = rb_define_class_under (EmModule, "Connection", rb_cObject);
957
1063
 
958
- rb_define_class_under (EmModule, "NoHandlerForAcceptedConnection", rb_eException);
1064
+ rb_define_class_under (EmModule, "NoHandlerForAcceptedConnection", rb_eRuntimeError);
1065
+ EM_eConnectionError = rb_define_class_under (EmModule, "ConnectionError", rb_eRuntimeError);
959
1066
  EM_eConnectionNotBound = rb_define_class_under (EmModule, "ConnectionNotBound", rb_eRuntimeError);
960
1067
  EM_eUnknownTimerFired = rb_define_class_under (EmModule, "UnknownTimerFired", rb_eRuntimeError);
1068
+ EM_eUnsupported = rb_define_class_under (EmModule, "Unsupported", rb_eRuntimeError);
961
1069
 
962
1070
  rb_define_module_function (EmModule, "initialize_event_machine", (VALUE(*)(...))t_initialize_event_machine, 0);
963
1071
  rb_define_module_function (EmModule, "run_machine", (VALUE(*)(...))t_run_machine_without_threads, 0);
@@ -977,10 +1085,19 @@ extern "C" void Init_rubyeventmachine()
977
1085
  rb_define_module_function (EmModule, "bind_connect_server", (VALUE(*)(...))t_bind_connect_server, 4);
978
1086
  rb_define_module_function (EmModule, "connect_unix_server", (VALUE(*)(...))t_connect_unix_server, 1);
979
1087
 
980
- rb_define_module_function (EmModule, "attach_fd", (VALUE (*)(...))t_attach_fd, 3);
1088
+ rb_define_module_function (EmModule, "attach_fd", (VALUE (*)(...))t_attach_fd, 2);
981
1089
  rb_define_module_function (EmModule, "detach_fd", (VALUE (*)(...))t_detach_fd, 1);
1090
+ rb_define_module_function (EmModule, "get_sock_opt", (VALUE (*)(...))t_get_sock_opt, 3);
1091
+ rb_define_module_function (EmModule, "set_notify_readable", (VALUE (*)(...))t_set_notify_readable, 2);
1092
+ rb_define_module_function (EmModule, "set_notify_writable", (VALUE (*)(...))t_set_notify_writable, 2);
1093
+ rb_define_module_function (EmModule, "is_notify_readable", (VALUE (*)(...))t_is_notify_readable, 1);
1094
+ rb_define_module_function (EmModule, "is_notify_writable", (VALUE (*)(...))t_is_notify_writable, 1);
1095
+
1096
+ rb_define_module_function (EmModule, "pause_connection", (VALUE (*)(...))t_pause, 1);
1097
+ rb_define_module_function (EmModule, "resume_connection", (VALUE (*)(...))t_resume, 1);
1098
+ rb_define_module_function (EmModule, "connection_paused?", (VALUE (*)(...))t_paused_p, 1);
982
1099
 
983
- rb_define_module_function (EmModule, "start_proxy", (VALUE (*)(...))t_start_proxy, 2);
1100
+ rb_define_module_function (EmModule, "start_proxy", (VALUE (*)(...))t_start_proxy, 3);
984
1101
  rb_define_module_function (EmModule, "stop_proxy", (VALUE (*)(...))t_stop_proxy, 1);
985
1102
 
986
1103
  rb_define_module_function (EmModule, "watch_filename", (VALUE (*)(...))t_watch_filename, 1);
@@ -1015,6 +1132,8 @@ extern "C" void Init_rubyeventmachine()
1015
1132
  rb_define_module_function (EmModule, "get_subprocess_status", (VALUE(*)(...))t_get_subprocess_status, 1);
1016
1133
  rb_define_module_function (EmModule, "get_comm_inactivity_timeout", (VALUE(*)(...))t_get_comm_inactivity_timeout, 1);
1017
1134
  rb_define_module_function (EmModule, "set_comm_inactivity_timeout", (VALUE(*)(...))t_set_comm_inactivity_timeout, 2);
1135
+ rb_define_module_function (EmModule, "get_pending_connect_timeout", (VALUE(*)(...))t_get_pending_connect_timeout, 1);
1136
+ rb_define_module_function (EmModule, "set_pending_connect_timeout", (VALUE(*)(...))t_set_pending_connect_timeout, 2);
1018
1137
  rb_define_module_function (EmModule, "set_rlimit_nofile", (VALUE(*)(...))t_set_rlimit_nofile, 1);
1019
1138
  rb_define_module_function (EmModule, "get_connection_count", (VALUE(*)(...))t_get_connection_count, 0);
1020
1139