eventmachine 1.0.0.beta.4-java → 1.0.0-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.
@@ -17,7 +17,7 @@ add_define 'BUILD_FOR_RUBY'
17
17
  # Minor platform details between *nix and Windows:
18
18
 
19
19
  if RUBY_PLATFORM =~ /(mswin|mingw|bccwin)/
20
- GNU_CHAIN = $1 == 'mingw'
20
+ GNU_CHAIN = ENV['CROSS_COMPILING'] or $1 == 'mingw'
21
21
  OS_WIN32 = true
22
22
  add_define "OS_WIN32"
23
23
  else
@@ -26,6 +26,15 @@ else
26
26
  add_define 'OS_UNIX'
27
27
  end
28
28
 
29
+ # Adjust number of file descriptors (FD) on Windows
30
+
31
+ if RbConfig::CONFIG["host_os"] =~ /mingw/
32
+ found = RbConfig::CONFIG.values_at("CFLAGS", "CPPFLAGS").
33
+ any? { |v| v.include?("FD_SETSIZE") }
34
+
35
+ add_define "FD_SETSIZE=32767" unless found
36
+ end
37
+
29
38
  # Main platform invariances:
30
39
 
31
40
  case RUBY_PLATFORM
@@ -77,9 +86,18 @@ when /aix/
77
86
  # on Unix we need a g++ link, not gcc.
78
87
  CONFIG['LDSHARED'] = "$(CXX) -shared -Wl,-G"
79
88
 
89
+ when /cygwin/
90
+ # For rubies built with Cygwin, CXX may be set to CC, which is just
91
+ # a wrapper for gcc.
92
+ # This will compile, but it will not link to the C++ std library.
93
+ # Explicitly set CXX to use g++.
94
+ CONFIG['CXX'] = "g++"
95
+ # on Unix we need a g++ link, not gcc.
96
+ CONFIG['LDSHARED'] = "$(CXX) -shared"
97
+
80
98
  else
81
99
  # on Unix we need a g++ link, not gcc.
82
100
  CONFIG['LDSHARED'] = "$(CXX) -shared"
83
101
  end
84
102
 
85
- create_makefile "fastfilereaderext"
103
+ create_makefile "fastfilereaderext"
@@ -82,7 +82,8 @@ typedef int SOCKET;
82
82
 
83
83
  #ifdef OS_WIN32
84
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
85
+ // 18Jun12: fd_setsize must be changed in the ruby binary (not in this extension). redefining it also causes segvs, see eventmachine/eventmachine#333
86
+ //#define FD_SETSIZE 1024
86
87
 
87
88
  #define WIN32_LEAN_AND_MEAN
88
89
  #include <windows.h>
@@ -233,7 +233,7 @@ static VALUE t_add_oneshot_timer (VALUE self, VALUE interval)
233
233
  {
234
234
  const unsigned long f = evma_install_oneshot_timer (FIX2INT (interval));
235
235
  if (!f)
236
- rb_raise (rb_eRuntimeError, "ran out of timers; use #set_max_timers to increase limit");
236
+ rb_raise (rb_eRuntimeError, "%s", "ran out of timers; use #set_max_timers to increase limit");
237
237
  return ULONG2NUM (f);
238
238
  }
239
239
 
@@ -246,7 +246,7 @@ static VALUE t_start_server (VALUE self, VALUE server, VALUE port)
246
246
  {
247
247
  const unsigned long f = evma_create_tcp_server (StringValuePtr(server), FIX2INT(port));
248
248
  if (!f)
249
- rb_raise (rb_eRuntimeError, "no acceptor (port is in use or requires root privileges)");
249
+ rb_raise (rb_eRuntimeError, "%s", "no acceptor (port is in use or requires root privileges)");
250
250
  return ULONG2NUM (f);
251
251
  }
252
252
 
@@ -269,7 +269,7 @@ static VALUE t_start_unix_server (VALUE self, VALUE filename)
269
269
  {
270
270
  const unsigned long f = evma_create_unix_domain_server (StringValuePtr(filename));
271
271
  if (!f)
272
- rb_raise (rb_eRuntimeError, "no unix-domain acceptor");
272
+ rb_raise (rb_eRuntimeError, "%s", "no unix-domain acceptor");
273
273
  return ULONG2NUM (f);
274
274
  }
275
275
 
@@ -504,10 +504,10 @@ static VALUE t_connect_server (VALUE self, VALUE server, VALUE port)
504
504
  try {
505
505
  const unsigned long f = evma_connect_to_server (NULL, 0, StringValuePtr(server), NUM2INT(port));
506
506
  if (!f)
507
- rb_raise (EM_eConnectionError, "no connection");
507
+ rb_raise (EM_eConnectionError, "%s", "no connection");
508
508
  return ULONG2NUM (f);
509
509
  } catch (std::runtime_error e) {
510
- rb_raise (EM_eConnectionError, e.what());
510
+ rb_raise (EM_eConnectionError, "%s", e.what());
511
511
  }
512
512
  return Qnil;
513
513
  }
@@ -525,10 +525,10 @@ static VALUE t_bind_connect_server (VALUE self, VALUE bind_addr, VALUE bind_port
525
525
  try {
526
526
  const unsigned long f = evma_connect_to_server (StringValuePtr(bind_addr), NUM2INT(bind_port), StringValuePtr(server), NUM2INT(port));
527
527
  if (!f)
528
- rb_raise (EM_eConnectionError, "no connection");
528
+ rb_raise (EM_eConnectionError, "%s", "no connection");
529
529
  return ULONG2NUM (f);
530
530
  } catch (std::runtime_error e) {
531
- rb_raise (EM_eConnectionError, e.what());
531
+ rb_raise (EM_eConnectionError, "%s", e.what());
532
532
  }
533
533
  return Qnil;
534
534
  }
@@ -541,7 +541,7 @@ static VALUE t_connect_unix_server (VALUE self, VALUE serversocket)
541
541
  {
542
542
  const unsigned long f = evma_connect_to_unix_server (StringValuePtr(serversocket));
543
543
  if (!f)
544
- rb_raise (rb_eRuntimeError, "no connection");
544
+ rb_raise (rb_eRuntimeError, "%s", "no connection");
545
545
  return ULONG2NUM (f);
546
546
  }
547
547
 
@@ -553,7 +553,7 @@ static VALUE t_attach_fd (VALUE self, VALUE file_descriptor, VALUE watch_mode)
553
553
  {
554
554
  const unsigned long f = evma_attach_fd (NUM2INT(file_descriptor), watch_mode == Qtrue);
555
555
  if (!f)
556
- rb_raise (rb_eRuntimeError, "no connection");
556
+ rb_raise (rb_eRuntimeError, "%s", "no connection");
557
557
  return ULONG2NUM (f);
558
558
  }
559
559
 
@@ -686,6 +686,15 @@ static VALUE t_paused_p (VALUE self, VALUE signature)
686
686
  return evma_is_paused(NUM2ULONG (signature)) ? Qtrue : Qfalse;
687
687
  }
688
688
 
689
+ /*********************
690
+ t_num_close_scheduled
691
+ *********************/
692
+
693
+ static VALUE t_num_close_scheduled (VALUE self)
694
+ {
695
+ return INT2FIX(evma_num_close_scheduled());
696
+ }
697
+
689
698
  /*****************
690
699
  t_open_udp_socket
691
700
  *****************/
@@ -694,7 +703,7 @@ static VALUE t_open_udp_socket (VALUE self, VALUE server, VALUE port)
694
703
  {
695
704
  const unsigned long f = evma_open_datagram_socket (StringValuePtr(server), FIX2INT(port));
696
705
  if (!f)
697
- rb_raise (rb_eRuntimeError, "no datagram socket");
706
+ rb_raise (rb_eRuntimeError, "%s", "no datagram socket");
698
707
  return ULONG2NUM (f);
699
708
  }
700
709
 
@@ -796,7 +805,7 @@ static VALUE t_invoke_popen (VALUE self, VALUE cmd)
796
805
  int len = RARRAY (cmd)->len;
797
806
  #endif
798
807
  if (len >= 2048)
799
- rb_raise (rb_eRuntimeError, "too many arguments to popen");
808
+ rb_raise (rb_eRuntimeError, "%s", "too many arguments to popen");
800
809
  char *strings [2048];
801
810
  for (int i=0; i < len; i++) {
802
811
  VALUE ix = INT2FIX (i);
@@ -825,7 +834,7 @@ static VALUE t_read_keyboard (VALUE self)
825
834
  {
826
835
  const unsigned long f = evma_open_keyboard();
827
836
  if (!f)
828
- rb_raise (rb_eRuntimeError, "no keyboard reader");
837
+ rb_raise (rb_eRuntimeError, "%s", "no keyboard reader");
829
838
  return ULONG2NUM (f);
830
839
  }
831
840
 
@@ -839,7 +848,7 @@ static VALUE t_watch_filename (VALUE self, VALUE fname)
839
848
  try {
840
849
  return ULONG2NUM(evma_watch_filename(StringValuePtr(fname)));
841
850
  } catch (std::runtime_error e) {
842
- rb_raise (EM_eUnsupported, e.what());
851
+ rb_raise (EM_eUnsupported, "%s", e.what());
843
852
  }
844
853
  return Qnil;
845
854
  }
@@ -865,7 +874,7 @@ static VALUE t_watch_pid (VALUE self, VALUE pid)
865
874
  try {
866
875
  return ULONG2NUM(evma_watch_pid(NUM2INT(pid)));
867
876
  } catch (std::runtime_error e) {
868
- rb_raise (EM_eUnsupported, e.what());
877
+ rb_raise (EM_eUnsupported, "%s", e.what());
869
878
  }
870
879
  return Qnil;
871
880
  }
@@ -912,7 +921,7 @@ t__epoll_set
912
921
  static VALUE t__epoll_set (VALUE self, VALUE val)
913
922
  {
914
923
  if (t__epoll_p(self) == Qfalse)
915
- rb_raise (EM_eUnsupported, "epoll is not supported on this platform");
924
+ rb_raise (EM_eUnsupported, "%s", "epoll is not supported on this platform");
916
925
 
917
926
  evma_set_epoll (val == Qtrue ? 1 : 0);
918
927
  return val;
@@ -949,7 +958,7 @@ t__kqueue_set
949
958
  static VALUE t__kqueue_set (VALUE self, VALUE val)
950
959
  {
951
960
  if (t__kqueue_p(self) == Qfalse)
952
- rb_raise (EM_eUnsupported, "kqueue is not supported on this platform");
961
+ rb_raise (EM_eUnsupported, "%s", "kqueue is not supported on this platform");
953
962
 
954
963
  evma_set_kqueue (val == Qtrue ? 1 : 0);
955
964
  return val;
@@ -987,7 +996,7 @@ static VALUE t_send_file_data (VALUE self, VALUE signature, VALUE filename)
987
996
 
988
997
  int b = evma_send_file_data_to_connection (NUM2ULONG (signature), StringValuePtr(filename));
989
998
  if (b == -1)
990
- rb_raise(rb_eRuntimeError, "File too large. send_file_data() supports files under 32k.");
999
+ rb_raise(rb_eRuntimeError, "%s", "File too large. send_file_data() supports files under 32k.");
991
1000
  if (b > 0) {
992
1001
  char *err = strerror (b);
993
1002
  char buf[1024];
@@ -1065,7 +1074,7 @@ static VALUE t_start_proxy (VALUE self, VALUE from, VALUE to, VALUE bufsize, VAL
1065
1074
  try {
1066
1075
  evma_start_proxy(NUM2ULONG (from), NUM2ULONG (to), NUM2ULONG(bufsize), NUM2ULONG(length));
1067
1076
  } catch (std::runtime_error e) {
1068
- rb_raise (EM_eConnectionError, e.what());
1077
+ rb_raise (EM_eConnectionError, "%s", e.what());
1069
1078
  }
1070
1079
  return Qnil;
1071
1080
  }
@@ -1080,11 +1089,49 @@ static VALUE t_stop_proxy (VALUE self, VALUE from)
1080
1089
  try{
1081
1090
  evma_stop_proxy(NUM2ULONG (from));
1082
1091
  } catch (std::runtime_error e) {
1083
- rb_raise (EM_eConnectionError, e.what());
1092
+ rb_raise (EM_eConnectionError, "%s", e.what());
1084
1093
  }
1085
1094
  return Qnil;
1086
1095
  }
1087
1096
 
1097
+ /***************
1098
+ t_proxied_bytes
1099
+ ****************/
1100
+
1101
+ static VALUE t_proxied_bytes (VALUE self, VALUE from)
1102
+ {
1103
+ try{
1104
+ return ULONG2NUM(evma_proxied_bytes(NUM2ULONG (from)));
1105
+ } catch (std::runtime_error e) {
1106
+ rb_raise (EM_eConnectionError, "%s", e.what());
1107
+ }
1108
+ return Qnil;
1109
+ }
1110
+
1111
+ /***************
1112
+ t_get_idle_time
1113
+ ****************/
1114
+
1115
+ static VALUE t_get_idle_time (VALUE self, VALUE from)
1116
+ {
1117
+ try{
1118
+ uint64_t current_time = evma_get_current_loop_time();
1119
+ uint64_t time = evma_get_last_activity_time(NUM2ULONG (from));
1120
+ if (current_time != 0 && time != 0) {
1121
+ if (time >= current_time)
1122
+ return ULONG2NUM(0);
1123
+ else {
1124
+ uint64_t diff = current_time - time;
1125
+ float seconds = diff / (1000.0*1000.0);
1126
+ return rb_float_new(seconds);
1127
+ }
1128
+ return Qnil;
1129
+ }
1130
+ } catch (std::runtime_error e) {
1131
+ rb_raise (EM_eConnectionError, "%s", e.what());
1132
+ }
1133
+ return Qnil;
1134
+ }
1088
1135
 
1089
1136
  /************************
1090
1137
  t_get_heartbeat_interval
@@ -1180,9 +1227,11 @@ extern "C" void Init_rubyeventmachine()
1180
1227
  rb_define_module_function (EmModule, "pause_connection", (VALUE (*)(...))t_pause, 1);
1181
1228
  rb_define_module_function (EmModule, "resume_connection", (VALUE (*)(...))t_resume, 1);
1182
1229
  rb_define_module_function (EmModule, "connection_paused?", (VALUE (*)(...))t_paused_p, 1);
1230
+ rb_define_module_function (EmModule, "num_close_scheduled", (VALUE (*)(...))t_num_close_scheduled, 0);
1183
1231
 
1184
1232
  rb_define_module_function (EmModule, "start_proxy", (VALUE (*)(...))t_start_proxy, 4);
1185
1233
  rb_define_module_function (EmModule, "stop_proxy", (VALUE (*)(...))t_stop_proxy, 1);
1234
+ rb_define_module_function (EmModule, "get_proxied_bytes", (VALUE (*)(...))t_proxied_bytes, 1);
1186
1235
 
1187
1236
  rb_define_module_function (EmModule, "watch_filename", (VALUE (*)(...))t_watch_filename, 1);
1188
1237
  rb_define_module_function (EmModule, "unwatch_filename", (VALUE (*)(...))t_unwatch_filename, 1);
@@ -1206,6 +1255,7 @@ extern "C" void Init_rubyeventmachine()
1206
1255
  rb_define_module_function (EmModule, "send_file_data", (VALUE(*)(...))t_send_file_data, 2);
1207
1256
  rb_define_module_function (EmModule, "get_heartbeat_interval", (VALUE(*)(...))t_get_heartbeat_interval, 0);
1208
1257
  rb_define_module_function (EmModule, "set_heartbeat_interval", (VALUE(*)(...))t_set_heartbeat_interval, 1);
1258
+ rb_define_module_function (EmModule, "get_idle_time", (VALUE(*)(...))t_get_idle_time, 1);
1209
1259
 
1210
1260
  rb_define_module_function (EmModule, "get_peername", (VALUE(*)(...))t_get_peername, 1);
1211
1261
  rb_define_module_function (EmModule, "get_sockname", (VALUE(*)(...))t_get_sockname, 1);
@@ -137,7 +137,7 @@ SslContext_t::SslContext_t (bool is_server, const string &privkeyfile, const str
137
137
  bLibraryInitialized = true;
138
138
  SSL_library_init();
139
139
  OpenSSL_add_ssl_algorithms();
140
- OpenSSL_add_all_algorithms();
140
+ OpenSSL_add_all_algorithms();
141
141
  SSL_load_error_strings();
142
142
  ERR_load_crypto_strings();
143
143
 
@@ -151,6 +151,9 @@ SslContext_t::SslContext_t (bool is_server, const string &privkeyfile, const str
151
151
 
152
152
  SSL_CTX_set_options (pCtx, SSL_OP_ALL);
153
153
  //SSL_CTX_set_options (pCtx, (SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3));
154
+ #ifdef SSL_MODE_RELEASE_BUFFERS
155
+ SSL_CTX_set_mode (pCtx, SSL_MODE_RELEASE_BUFFERS);
156
+ #endif
154
157
 
155
158
  if (is_server) {
156
159
  // The SSL_CTX calls here do NOT allocate memory.
@@ -524,6 +524,10 @@ public class EmReactor {
524
524
  return Connections.get(sig).getPeerName();
525
525
  }
526
526
 
527
+ public Object[] getSockName (long sig) {
528
+ return Connections.get(sig).getSockName();
529
+ }
530
+
527
531
  public long attachChannel (SocketChannel sc, boolean watch_mode) {
528
532
  long b = createBinding();
529
533
 
@@ -60,6 +60,7 @@ public interface EventableChannel {
60
60
  public void setCommInactivityTimeout (long seconds);
61
61
 
62
62
  public Object[] getPeerName();
63
+ public Object[] getSockName();
63
64
 
64
65
  public boolean isWatchOnly();
65
66
 
@@ -183,6 +183,12 @@ public class EventableDatagramChannel implements EventableChannel {
183
183
  }
184
184
  }
185
185
 
186
+ public Object[] getSockName () {
187
+ DatagramSocket socket = channel.socket();
188
+ return new Object[]{ socket.getLocalPort(),
189
+ socket.getLocalAddress().getHostAddress() };
190
+ }
191
+
186
192
  public boolean isWatchOnly() { return false; }
187
193
  public boolean isNotifyReadable() { return false; }
188
194
  public boolean isNotifyWritable() { return false; }
@@ -302,6 +302,12 @@ public class EventableSocketChannel implements EventableChannel {
302
302
  return new Object[]{ sock.getPort(), sock.getInetAddress().getHostAddress() };
303
303
  }
304
304
 
305
+ public Object[] getSockName () {
306
+ Socket sock = channel.socket();
307
+ return new Object[]{ sock.getLocalPort(),
308
+ sock.getLocalAddress().getHostAddress() };
309
+ }
310
+
305
311
  public void setWatchOnly() {
306
312
  bWatchOnly = true;
307
313
  updateEvents();
@@ -238,6 +238,12 @@ module EventMachine
238
238
  EventMachine::disable_proxy(self)
239
239
  end
240
240
 
241
+ # The number of bytes proxied to another connection. Reset to zero when
242
+ # EventMachine::Connection#proxy_incoming_to is called, and incremented whenever data is proxied.
243
+ def get_proxied_bytes
244
+ EventMachine::get_proxied_bytes(@signature)
245
+ end
246
+
241
247
  # EventMachine::Connection#close_connection is called only by user code, and never
242
248
  # by the event loop. You may call this method against a connection object in any
243
249
  # callback handler, whether or not the callback was made against the connection
@@ -570,6 +576,11 @@ module EventMachine
570
576
  EventMachine::get_subprocess_status @signature
571
577
  end
572
578
 
579
+ # The number of seconds since the last send/receive activity on this connection.
580
+ def get_idle_time
581
+ EventMachine::get_idle_time @signature
582
+ end
583
+
573
584
  # comm_inactivity_timeout returns the current value (float in seconds) of the inactivity-timeout
574
585
  # property of network-connection and datagram-socket objects. A nonzero value
575
586
  # indicates that the connection or socket will automatically be closed if no read or write
@@ -122,7 +122,10 @@ module EventMachine
122
122
 
123
123
  def failure resource
124
124
  if @on_error
125
+ @contents.delete resource
125
126
  @on_error.call resource
127
+ # Prevent users from calling a leak.
128
+ @removed.delete resource
126
129
  else
127
130
  requeue resource
128
131
  end
@@ -140,7 +143,9 @@ module EventMachine
140
143
  else
141
144
  raise ArgumentError, "deferrable expected from work"
142
145
  end
146
+ rescue Exception
147
+ failure resource
148
+ raise
143
149
  end
144
-
145
150
  end
146
- end
151
+ end
@@ -31,38 +31,38 @@ module EventMachine
31
31
  # Simple SMTP client
32
32
  #
33
33
  # @example
34
- # email = EM::Protocols::SmtpClient.send(
35
- # :domain=>"example.com",
36
- # :host=>'localhost',
37
- # :port=>25, # optional, defaults 25
38
- # :starttls=>true, # use ssl
39
- # :from=>"sender@example.com",
40
- # :to=> ["to_1@example.com", "to_2@example.com"],
41
- # :header=> {"Subject" => "This is a subject line"},
42
- # :body=> "This is the body of the email"
43
- # )
44
- # email.callback{
45
- # puts 'Email sent!'
46
- # }
47
- # email.errback{ |e|
48
- # puts 'Email failed!'
49
- # }
34
+ # email = EM::Protocols::SmtpClient.send(
35
+ # :domain=>"example.com",
36
+ # :host=>'localhost',
37
+ # :port=>25, # optional, defaults 25
38
+ # :starttls=>true, # use ssl
39
+ # :from=>"sender@example.com",
40
+ # :to=> ["to_1@example.com", "to_2@example.com"],
41
+ # :header=> {"Subject" => "This is a subject line"},
42
+ # :body=> "This is the body of the email"
43
+ # )
44
+ # email.callback{
45
+ # puts 'Email sent!'
46
+ # }
47
+ # email.errback{ |e|
48
+ # puts 'Email failed!'
49
+ # }
50
50
  #
51
51
  # Sending generated emails (using mailfactory)
52
52
  #
53
- # mail = MailFactory.new
54
- # mail.to = 'someone@site.co'
55
- # mail.from = 'me@site.com'
56
- # mail.subject = 'hi!'
57
- # mail.text = 'hello world'
58
- # mail.html = '<h1>hello world</h1>'
53
+ # mail = MailFactory.new
54
+ # mail.to = 'someone@site.co'
55
+ # mail.from = 'me@site.com'
56
+ # mail.subject = 'hi!'
57
+ # mail.text = 'hello world'
58
+ # mail.html = '<h1>hello world</h1>'
59
59
  #
60
- # email = EM::P::SmtpClient.send(
61
- # :domain=>'site.com',
62
- # :from=>mail.from,
63
- # :to=>mail.to,
64
- # :content=>"#{mail.to_s}\r\n.\r\n"
65
- # )
60
+ # email = EM::P::SmtpClient.send(
61
+ # :domain=>'site.com',
62
+ # :from=>mail.from,
63
+ # :to=>mail.to,
64
+ # :content=>"#{mail.to_s}\r\n.\r\n"
65
+ # )
66
66
  #
67
67
  class SmtpClient < Connection
68
68
  include EventMachine::Deferrable