eventmachine 1.0.0.beta.4-java → 1.0.0-java

Sign up to get free protection for your applications and to get access to all the features.
@@ -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