Permalink
Browse files

Allow use of an existing file descriptor for an EM server

  • Loading branch information...
1 parent ba83488 commit f41e037d39a51f53d4c6599e89c61258614510d7 @gdb gdb committed Dec 13, 2011
Showing with 39 additions and 10 deletions.
  1. +10 −0 ext/cmain.cpp
  2. +9 −9 ext/em.cpp
  3. +1 −0 ext/em.h
  4. +1 −0 ext/eventmachine.h
  5. +13 −0 ext/rubymain.cpp
  6. +5 −1 lib/eventmachine.rb
View
@@ -282,6 +282,16 @@ extern "C" const unsigned long evma_create_unix_domain_server (const char *filen
return EventMachine->CreateUnixDomainServer (filename);
}
+/**********************
+evma_create_tcp_server
+**********************/
+
+extern "C" const unsigned long evma_reuse_server (int descriptor)
+{
+ ensure_eventmachine("evma_reuse_server");
+ return EventMachine->OutputBinding (descriptor);
+}
+
/*************************
evma_open_datagram_socket
*************************/
View
@@ -1559,22 +1559,22 @@ const unsigned long EventMachine_t::CreateTcpServer (const char *server, int por
}
}
- { // Looking good.
- AcceptorDescriptor *ad = new AcceptorDescriptor (sd_accept, this);
- if (!ad)
- throw std::runtime_error ("unable to allocate acceptor");
- Add (ad);
- output_binding = ad->GetBinding();
- }
-
- return output_binding;
+ return OutputBinding(sd_accept);
fail:
if (sd_accept != INVALID_SOCKET)
close (sd_accept);
return 0;
}
+const unsigned long EventMachine_t::OutputBinding(int sd_accept)
+{
+ AcceptorDescriptor *ad = new AcceptorDescriptor (sd_accept, this);
+ if (!ad)
+ throw std::runtime_error ("unable to allocate acceptor");
+ Add (ad);
+ return ad->GetBinding();
+}
/**********************************
EventMachine_t::OpenDatagramSocket
View
@@ -82,6 +82,7 @@ class EventMachine_t
const unsigned long ConnectToUnixServer (const char *);
const unsigned long CreateTcpServer (const char *, int);
+ const unsigned long OutputBinding (int);
const unsigned long OpenDatagramSocket (const char *, int);
const unsigned long CreateUnixDomainServer (const char*);
const unsigned long OpenKeyboard();
View
@@ -63,6 +63,7 @@ extern "C" {
void evma_stop_tcp_server (const unsigned long signature);
const unsigned long evma_create_tcp_server (const char *address, int port);
+ const unsigned long evma_reuse_server (int descriptor);
const unsigned long evma_create_unix_domain_server (const char *filename);
const unsigned long evma_open_datagram_socket (const char *server, int port);
const unsigned long evma_open_keyboard();
View
@@ -261,6 +261,18 @@ static VALUE t_stop_server (VALUE self, VALUE signature)
}
+/**************
+t_start_server
+**************/
+
+static VALUE t_reuse_server (VALUE self, VALUE descriptor)
+{
+ const unsigned long f = evma_reuse_server (FIX2INT(descriptor));
+ if (!f)
+ rb_raise (rb_eRuntimeError, "no acceptor (bad descriptor)");
+ return ULONG2NUM (f);
+}
+
/*******************
t_start_unix_server
*******************/
@@ -1203,6 +1215,7 @@ extern "C" void Init_rubyeventmachine()
rb_define_module_function (EmModule, "add_oneshot_timer", (VALUE(*)(...))t_add_oneshot_timer, 1);
rb_define_module_function (EmModule, "start_tcp_server", (VALUE(*)(...))t_start_server, 2);
rb_define_module_function (EmModule, "stop_tcp_server", (VALUE(*)(...))t_stop_server, 1);
+ rb_define_module_function (EmModule, "reuse_server", (VALUE(*)(...))t_reuse_server, 1);
rb_define_module_function (EmModule, "start_unix_server", (VALUE(*)(...))t_start_unix_server, 1);
rb_define_module_function (EmModule, "set_tls_parms", (VALUE(*)(...))t_set_tls_parms, 4);
rb_define_module_function (EmModule, "start_tls", (VALUE(*)(...))t_start_tls, 1);
View
@@ -524,8 +524,12 @@ def self.start_server server, port=nil, handler=nil, *args, &block
s = if port
start_tcp_server server, port
- else
+ elsif server.kind_of?(String)
start_unix_server server
+ elsif server.kind_of?(Fixnum)
+ reuse_server server
+ else
+ raise "Invalid server spec: #{server.inspect}, #{port.inspect}"
end
@acceptors[s] = [klass,args,block]
s

1 comment on commit f41e037

tmm1 commented on f41e037 May 29, 2012

See also eventmachine/eventmachine#271. It includes autoclose=false to prevent the reactor from closing the external acceptor on shutdown, and ensures SetSocketNonblocking is always called on the incoming listener.

Please sign in to comment.