Ticket #34: lotsa_sockets_updated.2.diff
| File lotsa_sockets_updated.2.diff, 14.8 kB (added by raggi, 5 months ago) |
|---|
-
em.cpp
old new 64 64 MaxOutstandingTimers = count; 65 65 } 66 66 67 /************************ 68 * 69 If we're on linux, and using select, and sd >= FD_SETSIZE then reject it-- we can't fit it into a select! The problem being that with linux, the first parameter to select must be < FD_SETSIZE (it checks up to that many file descriptors). 70 i.e., if you get a file descriptor with a value as high as FD_SETSIZE, you cannot put that descriptor into an fd_set. (from http://www.delorie.com/gnu/docs/glibc/libc_248.html) 71 With windows, it appears that the total number of sockets it will cram into an fd_set is FD_SETSIZE, so...it basically ignores the call to FD_SET if the fd_set is already too populated, resulting in <cough> us losing a lot of data. So it's the same logic check, but it errs in different parameters. 72 http://doc.ddart.net/msdn/header/include/winsock.h.html -- we use winsock.h, not winsock2.h 73 74 todo add this to udp, well just about everything (?) Note that it's dangerous to 'close' it since it still will make it to select 75 76 So note that on linux descriptor numbers must be less than FD_SETSIZE, and on windows, the sum of descriptor counts must be < FD_SETSIZE. 77 ***********************/ 78 79 bool EventMachine_t::CantAffordNewSocket(int socket_number) 80 { 81 82 83 #ifndef OS_WIN32 84 if(bEpoll or bKqueue) 85 return 0; // can afford 86 if(socket_number >= (FD_SETSIZE -1)) // no idea why the -1 is necessary, but it seems to be on os x at least (errs without it) 87 return 1; 88 else 89 return 0; 90 #else 91 // we leave one for the loop break reader, etc. (seems to work). 92 if((Descriptors.size() + NewDescriptors.size()) < (FD_SETSIZE - 3)) 93 return 0; // can afford (not not afford) 94 else 95 return 1; // can't afford 96 #endif 97 98 } 99 100 void EventMachine_t::AssertValidDescriptorsLength() 101 { 102 if(bEpoll or bKqueue) 103 return; // always return true in this case--we don't run out. 104 int socket_count = Descriptors.size() + NewDescriptors.size(); 105 int max_allowed = FD_SETSIZE - 2; // since we need FD_SETSIZE -1 'slot' to hold the loop breaker 106 assert(socket_count <= max_allowed);; // should hold true for linux, too, by a freak of logic luck (if descriptors.size > FD_SETSIZE -2 then for sure we have one in there whose descriptor number >= FD_SETSIZE - 1 (?) 107 108 } 67 109 68 110 69 111 /****************************** … … 182 225 gTerminateSignalReceived = true; 183 226 } 184 227 228 /***************************** 229 EventMachine_t::GetTimerQuantumMills 230 ******************************/ 185 231 232 int EventMachine_t::GetTimerQuantumMills () 233 { 234 return Quantum.tv_sec * 1000 + Quantum.tv_usec / 1000; 235 } 186 236 237 187 238 /******************************* 188 239 EventMachine_t::SetTimerQuantum 189 240 *******************************/ -
em.h
old new 82 82 void ArmKqueueWriter (EventableDescriptor*); 83 83 void ArmKqueueReader (EventableDescriptor*); 84 84 85 int GetTimerQuantumMills (); 86 void AssertValidDescriptorsLength(); 87 bool CantAffordNewSocket(int descriptor_number); 85 88 void SetTimerQuantum (int); 86 89 static void SetuidString (const char*); 87 90 static int SetRlimitNofile (int); … … 100 103 void _ModifyDescriptors(); 101 104 void _InitializeLoopBreaker(); 102 105 106 int _SelectOnceErrorControlled(); 103 107 bool _RunSelectOnce(); 104 108 bool _RunEpollOnce(); 105 109 bool _RunKqueueOnce(); -
eventmachine.h
old new 46 46 const char *evma_open_keyboard(); 47 47 void evma_set_tls_parms (const char *binding, const char *privatekey_filename, const char *certchain_filenane); 48 48 void evma_start_tls (const char *binding); 49 int evma_get_sockname (const char *binding, struct sockaddr*); 49 50 int evma_get_peername (const char *binding, struct sockaddr*); 50 51 int evma_get_sockname (const char *binding, struct sockaddr*); 51 52 int evma_get_subprocess_pid (const char *binding, pid_t*); … … 54 55 int evma_send_datagram (const char *binding, const char *data, int data_length, const char *address, int port); 55 56 int evma_get_comm_inactivity_timeout (const char *binding, /*out*/int *value); 56 57 int evma_set_comm_inactivity_timeout (const char *binding, /*in,out*/int *value); 58 int evma_get_timer_quantum_value (); /* passes it straight out */ 57 59 int evma_get_outbound_data_size (const char *binding); 58 60 int evma_send_file_data_to_connection (const char *binding, const char *filename); 59 61 -
rubymain.cpp
old new 304 305 305 306 const char *f = evma_connect_to_server (StringValuePtr(server), NUM2INT(port)); 306 307 if (!f || !*f) 307 rb_raise (rb_eRuntimeError, "no connection ");308 rb_raise (rb_eRuntimeError, "no connection t_connect_server meaning that the attempt to connect to the server failed somehow f_pointer == (%d)", f); 308 309 return rb_str_new2 (f); 309 310 } 310 311 … … 375 376 } 376 377 377 378 379 /***************** 380 t_get_timer_quantum_mills 381 Returns current timer quantum value 382 ******************/ 383 static VALUE 384 t_get_timer_quantum_mills (VALUE self) 385 { 386 return INT2NUM(evma_get_timer_quantum_value()); 387 } 378 388 389 379 390 /******************* 380 391 t_set_timer_quantum 381 392 *******************/ … … 596 607 rb_define_module_function (EmModule, "stop", (VALUE(*)(...))t_stop, 0); 597 608 rb_define_module_function (EmModule, "signal_loopbreak", (VALUE(*)(...))t_signal_loopbreak, 0); 598 609 rb_define_module_function (EmModule, "library_type", (VALUE(*)(...))t_library_type, 0); 610 rb_define_module_function (EmModule, "get_timer_quantum_mills", (VALUE(*)(...))t_get_timer_quantum_mills, 0); 599 611 rb_define_module_function (EmModule, "set_timer_quantum", (VALUE(*)(...))t_set_timer_quantum, 1); 600 612 rb_define_module_function (EmModule, "set_max_timer_count", (VALUE(*)(...))t_set_max_timer_count, 1); 601 613 rb_define_module_function (EmModule, "setuid_string", (VALUE(*)(...))t_setuid_string, 1); -
extconf.rb
old new 199 200 $CFLAGS += ' ' + flags.join(' ') 200 201 end 201 202 203 create_makefile "rubyeventmachine" 204 # now some hacks for it. ugh. 202 205 203 create_makefile "rubyeventmachine" 206 def replace_within_makefile this_string, with_this_string 207 makefile = File.read("Makefile") 208 makefile.gsub!(this_string, with_this_string) 209 File.open("Makefile", "wb").write(makefile) 210 end 211 212 if RUBY_PLATFORM =~ /mingw/ 213 print "noticed mingw, accomodating" 214 replace_within_file "DLDFLAGS =", "DLDFLAGS = -lstdc++ " # it misses these libs for some reason. silly makefile maker 215 end 216 217 uname = `uname -a` 218 if uname =~ /RELEASE_PPC/ # this known to work with Leopard, at least 219 print "noticed ppc, accomodating" 220 replace_within_makefile "i386", "ppc" # yep 221 end -
ed.cpp
old new 604 604 // so assert that as a sanity check. 605 605 // Don't bother to make sure nbytes is less than output_buffer because 606 606 // if it were we probably would have crashed already. 607 assert (nbytes > 0); 607 // this really can crash todo look into it: 608 //if(nbytes <= 0) 609 // printf("arr nbytes == %d", nbytes); 610 //assert (nbytes > 0); 608 611 609 612 assert (GetSocket() != INVALID_SOCKET); 610 613 int bytes_written = send (GetSocket(), output_buffer, nbytes, 0); … … 926 930 continue; 927 931 } 928 932 929 933 if(MyEventMachine->CantAffordNewSocket(sd)) 934 { 935 printf("ignoring too large of a socket for accept! aaah!"); 936 shutdown (sd, 1); 937 closesocket (sd); 938 continue; 939 } 940 930 941 // Disable slow-start (Nagle algorithm). Eventually make this configurable. 931 942 int one = 1; 932 943 setsockopt (sd, IPPROTO_TCP, TCP_NODELAY, (char*) &one, sizeof(one)); … … 950 961 MyEventMachine->ArmKqueueReader (cd); 951 962 #endif 952 963 } 964 MyEventMachine->AssertValidDescriptorsLength(); 953 965 954 966 } 955 967
