Ticket #34: lotsa_sockets_updated.diff
| File lotsa_sockets_updated.diff, 27.0 kB (added by rogerdpack, 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 /****************************** … … 153 195 /* Temporary. 154 196 * See comments under _UseEpoll. 155 197 */ 156 198 157 199 #ifdef HAVE_KQUEUE 158 200 bKqueue = true; 201 #else 159 202 #endif 160 203 } 161 204 … … 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 *******************************/ … … 463 514 // descriptor is closed anyway. This is different from the case where 464 515 // the socket has already been closed but the descriptor in the ED object 465 516 // hasn't yet been set to INVALID_SOCKET. 466 int i, j;467 int nSockets = Descriptors.size();468 for (i=0, j=0; i < nSockets; i++) {469 EventableDescriptor *ed = Descriptors[i];470 assert (ed);471 if (ed->ShouldDelete()) {517 int i, j; 518 int nSockets = Descriptors.size(); 519 for (i=0, j=0; i < nSockets; i++) { 520 EventableDescriptor *ed = Descriptors[i]; 521 assert (ed); 522 if (ed->ShouldDelete()) { 472 523 if (ed->GetSocket() != INVALID_SOCKET) { 473 524 assert (bEpoll); // wouldn't be in this method otherwise. 474 525 assert (epfd != -1); … … 479 530 snprintf (buf, sizeof(buf)-1, "unable to delete epoll event: %s", strerror(errno)); 480 531 throw std::runtime_error (buf); 481 532 } 482 }533 } 483 534 484 535 ModifiedDescriptors.erase (ed); 485 536 delete ed; … … 658 709 #endif 659 710 } 660 711 712 /****************************** 713 EventMachine_t::_SelectOnceErrorController 714 ******************************/ 661 715 716 int EventMachine_t::_SelectOnceErrorControlled() // for win32 only -- this does help, in some instances. There seems to be some lurking other problems, too, though--like why don't connections close right, and then sometimes select still fails--and in a bad way. 717 { 718 /* Some windows notes (this function used mostly for windows--I hope) 719 todo run on linux EINVAL, too 720 note that windows sometimes, for some reason if you have open sockets, then you do File.open (?) then one of your open sockets no longer responds to select. Maybe File.open 's file descriptor is ploughing a socket descriptor? 721 note also that on windows, server editions you can have more than 256 (msvcrt.dll) or 2048 (msvcrtXX.dll) file descriptors total, per process, so our setting FD_SETSIZE to 2048 might could use to be raised in those cases. But I'd say leaving it at 2048 is good till it becomes a problem for someone. 722 update--appears that it doesn't matter what you set FD_SETSIZE to be, it only 'works' up to 64, for some reason. Maybe ruby itself 'redefines' FD_SETSIZE to be low? So we need to set it? todo (there's a test that tests this, you can set FD_SETSIZE to whatever, run the test--it errs if you set it above 64! 723 it appears that even having this loop doesn't solve all the problems, as select sometimes returns '3' even when none of them even requested to read or write--probably corruption 724 */ 662 725 726 SelectData_t SelectData; 727 fd_set test_one_read, test_one_write, test_one_err; // do we need the err one, though? 728 FD_ZERO(&(SelectData.fdreads)); 729 FD_ZERO(&(SelectData.fdwrites)); 730 FD_ZERO(&test_one_read); 731 timeval tv_lpbr = {0,0}; 732 int select_return = EmSelect(LoopBreakerReader, &test_one_read, NULL, NULL, &tv_lpbr); 733 if(select_return < 0) 734 printf("arr bad loopbreaker! please report to EM\n\n\n"); 735 FD_SET (LoopBreakerReader, &(SelectData.fdreads)); 736 SelectData.maxsocket = LoopBreakerReader; 737 738 // prepare the sockets for reading and writing, with error checking this time 739 size_t i; 740 int failed_count = 0; 741 for (i = 0; i < Descriptors.size(); i++) { 742 timeval tv_zero = {0, 1}; // set this to actually wait a split second so that some weird weird weird obscure select failures will show through (if you set FD_SETSIZE to 2048, slam it, then sometimes select'ing on 0 doesn't work 'well enough' --it returns 1, then when you pass the whole group to select again, it errs. 743 EventableDescriptor *ed = Descriptors[i]; 744 assert (ed); 745 int sd = ed->GetSocket(); 746 assert (sd != INVALID_SOCKET); 747 FD_ZERO(&test_one_read); 748 FD_ZERO(&test_one_write); 749 750 if (ed->SelectForRead()) 751 { 752 int select_return = EmSelect(sd+1, &test_one_read, NULL, &test_one_err, &tv_zero); 753 if(select_return >= 0) 754 FD_SET (sd, &(SelectData.fdreads)); 755 else 756 { 757 failed_count++; 758 } 759 } 760 if (ed->SelectForWrite()) 761 { 762 FD_SET(sd, &test_one_write); 763 int select_return = EmSelect(sd+1, &test_one_write, NULL, NULL, &tv_zero); 764 if(select_return >= 0) 765 FD_SET (sd, &(SelectData.fdwrites)); 766 else 767 { 768 failed_count++; 769 } 770 } 771 772 if (SelectData.maxsocket < sd) 773 SelectData.maxsocket = sd; 774 } 775 776 //if(failed_count > 0) 777 // printf("at least one failed! -- FD_SETSIZE == %d, our descriptors size %d\n", FD_SETSIZE, Descriptors.size()); 778 779 return SelectData._Select(); 780 781 } 663 782 /****************************** 664 783 EventMachine_t::_RunSelectOnce 665 784 ******************************/ … … 679 798 //cerr << "X"; 680 799 681 800 /* This protection is now obsolete, because we will ALWAYS 682 * have at least one descriptor (the loop-breaker) to read. 801 * have at least one descriptor (the loop-breaker) to read. 683 802 */ 684 803 /* 685 804 if (Descriptors.size() == 0) { … … 689 808 return true; 690 809 #endif 691 810 #ifdef OS_WIN32 692 Sleep (200); 811 Sleep (200); 693 812 return true; 694 813 #endif 695 814 } … … 703 822 704 823 int maxsocket = 0; 705 824 */ 825 AssertValidDescriptorsLength(); 706 826 707 827 // Always read the loop-breaker reader. 708 828 // Changed 23Aug06, provisionally implemented for Windows with a UDP socket 709 829 // running on localhost with a randomly-chosen port. (*Puke*) 710 830 // Windows has a version of the Unix pipe() library function, but it doesn't 711 831 // give you back descriptors that are selectable. 832 712 833 FD_SET (LoopBreakerReader, &(SelectData.fdreads)); 713 834 if (SelectData.maxsocket < LoopBreakerReader) 714 835 SelectData.maxsocket = LoopBreakerReader; 715 836 716 837 // prepare the sockets for reading and writing 717 838 size_t i; 718 for (i = 0; i < Descriptors.size(); i++) { 839 for (i = 0; i < Descriptors.size(); i++) { // aren't we supposed to do this just once? 719 840 EventableDescriptor *ed = Descriptors[i]; 720 841 assert (ed); 721 842 int sd = ed->GetSocket(); 722 843 assert (sd != INVALID_SOCKET); 723 844 724 845 if (ed->SelectForRead()) 846 { 725 847 FD_SET (sd, &(SelectData.fdreads)); 848 } 726 849 if (ed->SelectForWrite()) 850 { 727 851 FD_SET (sd, &(SelectData.fdwrites)); 852 } 728 853 729 854 if (SelectData.maxsocket < sd) 730 855 SelectData.maxsocket = sd; 731 856 } 732 733 857 734 858 { // read and write the sockets 735 859 //timeval tv = {1, 0}; // Solaris fails if the microseconds member is >= 1000000. 736 860 //timeval tv = Quantum; 737 861 SelectData.tv = Quantum; 738 862 int s = SelectData._Select(); 863 #ifdef OS_WIN32 864 if(s<0) 865 { 866 #else 867 if(s==EINVAL) 868 { 869 printf("select EINVAL on linux unanticipated--please report to EM"); 870 #endif 871 s = _SelectOnceErrorControlled(); // hack to run it again with error checking on each socket, should it fail because of one--this until we can figure out and stamp out all win32 errors. Till then, just run select on error checked items. 872 } 873 739 874 //rb_thread_blocking_region(xxx,(void*)&SelectData,RB_UBF_DFL,0); 740 875 //int s = EmSelect (SelectData.maxsocket+1, &(SelectData.fdreads), &(SelectData.fdwrites), NULL, &(SelectData.tv)); 741 876 //int s = SelectData.nSockets; 877 742 878 if (s > 0) { 743 879 /* Changed 01Jun07. We used to handle the Loop-breaker right here. 744 880 * Now we do it AFTER all the regular descriptors. There's an … … 757 893 assert (sd != INVALID_SOCKET); 758 894 759 895 if (FD_ISSET (sd, &(SelectData.fdwrites))) 896 { 760 897 ed->Write(); 898 } 761 899 if (FD_ISSET (sd, &(SelectData.fdreads))) 900 { 762 901 ed->Read(); 902 } 763 903 } 764 904 765 905 if (FD_ISSET (LoopBreakerReader, &(SelectData.fdreads))) 906 { 766 907 _ReadLoopBreaker(); 908 } 767 909 } 768 910 else if (s < 0) { 769 911 // select can fail on error in a handful of ways. … … 772 914 // so keep the wait short. 773 915 timeval tv = {0, ((errno == EINTR) ? 5 : 50) * 1000}; 774 916 EmSelect (0, NULL, NULL, NULL, &tv); 917 #ifdef OS_WIN32 918 Sleep(100); 919 #endif 775 920 } 776 921 } 777 922 … … 974 1119 975 1120 // From here on, ALL error returns must close the socket. 976 1121 // Set the new socket nonblocking. 1122 if(CantAffordNewSocket(sd)) 1123 { 1124 //printf("connect ignoring too large of a socket for select bad 3.5"); 1125 closesocket (sd); 1126 return NULL; 1127 } 1128 977 1129 if (!SetSocketNonblocking (sd)) { 978 1130 closesocket (sd); 979 1131 return NULL; … … 983 1135 setsockopt (sd, IPPROTO_TCP, TCP_NODELAY, (char*) &one, sizeof(one)); 984 1136 985 1137 const char *out = NULL; 986 987 #ifdef OS_UNIX1138 1139 #ifdef OS_UNIX 988 1140 //if (connect (sd, (sockaddr*)&pin, sizeof pin) == 0) { 989 1141 if (connect (sd, bind_as, bind_size) == 0) { 990 1142 // This is a connect success, which Linux appears … … 1081 1233 } 1082 1234 else { 1083 1235 // The error from connect was something other then WSAEWOULDBLOCK. 1236 throw std::runtime_error ("unimplemented2"); 1084 1237 } 1085 1238 1086 1239 #endif 1087 1240 1241 AssertValidDescriptorsLength(); 1088 1242 if (out == NULL) 1089 1243 closesocket (sd); 1090 1244 return out; … … 1255 1409 if (sd_accept == INVALID_SOCKET) { 1256 1410 goto fail; 1257 1411 } 1412 // TODO ask about accepts, tho--should we just clear them or what? I assume so. 1413 if(CantAffordNewSocket(sd_accept)) 1414 { 1415 goto fail; 1416 } 1258 1417 1259 1418 /* 1260 1419 memset (&sin, 0, sizeof(sin)); … … 1322 1481 output_binding = ad->GetBinding().c_str(); 1323 1482 } 1324 1483 1484 AssertValidDescriptorsLength(); 1325 1485 return output_binding; 1326 1327 1486 fail: 1328 1487 if (sd_accept != INVALID_SOCKET) 1329 1488 closesocket (sd_accept); … … 1778 1937 1779 1938 1780 1939 //#endif // OS_UNIX 1781 -
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 206 206 return Qnil; 207 207 } 208 208 209 209 210 /******************** 210 211 t_get_subprocess_pid 211 212 ********************/ … … 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 31 31 have_library('gdi32') 32 32 exit 33 33 end 34 34 35 35 36 flags << "-D OS_WIN32" 36 37 flags << '-D BUILD_FOR_RUBY' … … 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 -
cmain.cpp
old new 35 35 // we're just being linked into. 36 36 //InstallSignalHandlers(); 37 37 if (EventMachine) 38 throw std::runtime_error (" already initialized");38 throw std::runtime_error ("evma_initialize_library already initialized"); 39 39 EventMachine = new EventMachine_t (cb); 40 40 if (bUseEpoll) 41 41 EventMachine->_UseEpoll(); … … 51 51 extern "C" void evma_release_library() 52 52 { 53 53 if (!EventMachine) 54 throw std::runtime_error (" not initialized");54 throw std::runtime_error ("evma_release_library not initialized"); 55 55 delete EventMachine; 56 56 EventMachine = NULL; 57 57 } … … 64 64 extern "C" void evma_run_machine() 65 65 { 66 66 if (!EventMachine) 67 throw std::runtime_error (" not initialized");67 throw std::runtime_error ("evma_run_machine not initialized"); 68 68 EventMachine->Run(); 69 69 } 70 70 … … 76 76 extern "C" const char *evma_install_oneshot_timer (int seconds) 77 77 { 78 78 if (!EventMachine) 79 throw std::runtime_error (" not initialized");79 throw std::runtime_error ("evma_install_oneshot_timer not initialized"); 80 80 return EventMachine->InstallOneshotTimer (seconds); 81 81 } 82 82 … … 88 88 extern "C" const char *evma_connect_to_server (const char *server, int port) 89 89 { 90 90 if (!EventMachine) 91 throw std::runtime_error (" not initialized");91 throw std::runtime_error ("evma_connect_to_server not initialized"); 92 92 return EventMachine->ConnectToServer (server, port); 93 93 } 94 94 … … 99 99 extern "C" const char *evma_connect_to_unix_server (const char *server) 100 100 { 101 101 if (!EventMachine) 102 throw std::runtime_error (" not initialized");102 throw std::runtime_error ("evma_connect_to_unix_server not initialized"); 103 103 return EventMachine->ConnectToUnixServer (server); 104 104 } 105 105 … … 111 111 extern "C" const char *evma_create_tcp_server (const char *address, int port) 112 112 { 113 113 if (!EventMachine) 114 throw std::runtime_error (" not initialized");114 throw std::runtime_error ("evma_create_tcp_server not initialized"); 115 115 return EventMachine->CreateTcpServer (address, port); 116 116 } 117 117 … … 122 122 extern "C" const char *evma_create_unix_domain_server (const char *filename) 123 123 { 124 124 if (!EventMachine) 125 throw std::runtime_error ("not initialized"); 125 { 126 throw std::runtime_error ("evma_create_unix_domain_server not initialized"); 127 } 126 128 return EventMachine->CreateUnixDomainServer (filename); 127 129 } 128 130 … … 133 135 extern "C" const char *evma_open_datagram_socket (const char *address, int port) 134 136 { 135 137 if (!EventMachine) 136 throw std::runtime_error (" not initialized");138 throw std::runtime_error ("evma_open_datagram_socket not initialized"); 137 139 return EventMachine->OpenDatagramSocket (address, port); 138 140 } 139 141 … … 144 146 extern "C" const char *evma_open_keyboard() 145 147 { 146 148 if (!EventMachine) 147 throw std::runtime_error (" not initialized");149 throw std::runtime_error ("evma_open_keyboard not initialized"); 148 150 return EventMachine->OpenKeyboard(); 149 151 } 150 152 … … 157 159 extern "C" int evma_send_data_to_connection (const char *binding, const char *data, int data_length) 158 160 { 159 161 if (!EventMachine) 160 throw std::runtime_error (" not initialized");162 throw std::runtime_error ("evma_send_data_to_connection not initialized"); 161 163 return ConnectionDescriptor::SendDataToConnection (binding, data, data_length); 162 164 } 163 165 … … 168 170 extern "C" int evma_send_datagram (const char *binding, const char *data, int data_length, const char *address, int port) 169 171 { 170 172 if (!EventMachine) 171 throw std::runtime_error (" not initialized");173 throw std::runtime_error ("evma_send_datagram not initialized"); 172 174 return DatagramDescriptor::SendDatagram (binding, data, data_length, address, port); 173 175 } 174 176 … … 180 182 extern "C" void evma_close_connection (const char *binding, int after_writing) 181 183 { 182 184 if (!EventMachine) 183 throw std::runtime_error (" not initialized");185 throw std::runtime_error ("evma_close_connection not initialized"); 184 186 ConnectionDescriptor::CloseConnection (binding, (after_writing ? true : false)); 185 187 } 186 188 … … 191 193 extern "C" int evma_report_connection_error_status (const char *binding) 192 194 { 193 195 if (!EventMachine) 194 throw std::runtime_error (" not initialized");196 throw std::runtime_error ("evma_report_connection_error_status not initialized"); 195 197 return ConnectionDescriptor::ReportErrorStatus (binding); 196 198 } 197 199 … … 202 204 extern "C" void evma_stop_tcp_server (const char *binding) 203 205 { 204 206 if (!EventMachine) 205 throw std::runtime_error (" not initialized");207 throw std::runtime_error ("evma_stop_tcp_server not initialized"); 206 208 AcceptorDescriptor::StopAcceptor (binding); 207 209 } 208 210 … … 214 216 extern "C" void evma_stop_machine() 215 217 { 216 218 if (!EventMachine) 217 throw std::runtime_error (" not initialized");219 throw std::runtime_error ("evma_stop_machine not initialized"); 218 220 EventMachine->ScheduleHalt(); 219 221 } 220 222 … … 226 228 extern "C" void evma_start_tls (const char *binding) 227 229 { 228 230 if (!EventMachine) 229 throw std::runtime_error (" not initialized");231 throw std::runtime_error ("evma_start_tls not initialized"); 230 232 EventableDescriptor *ed = dynamic_cast <EventableDescriptor*> (Bindable_t::GetObject (binding)); 231 233 if (ed) 232 234 ed->StartTls(); … … 239 241 extern "C" void evma_set_tls_parms (const char *binding, const char *privatekey_filename, const char *certchain_filename) 240 242 { 241 243 if (!EventMachine) 242 throw std::runtime_error (" not initialized");244 throw std::runtime_error ("evma_set_tls_parms not initialized"); 243 245 EventableDescriptor *ed = dynamic_cast <EventableDescriptor*> (Bindable_t::GetObject (binding)); 244 246 if (ed) 245 247 ed->SetTlsParms (privatekey_filename, certchain_filename); … … 253 255 extern "C" int evma_get_peername (const char *binding, struct sockaddr *sa) 254 256 { 255 257 if (!EventMachine) 256 throw std::runtime_error (" not initialized");258 throw std::runtime_error ("evma_get_peername not initialized"); 257 259 EventableDescriptor *ed = dynamic_cast <EventableDescriptor*> (Bindable_t::GetObject (binding)); 258 260 if (ed) { 259 261 return ed->GetPeername (sa) ? 1 : 0; … … 285 287 extern "C" int evma_get_subprocess_pid (const char *binding, pid_t *pid) 286 288 { 287 289 if (!EventMachine) 288 throw std::runtime_error (" not initialized");290 throw std::runtime_error ("evma_get_subprocess_pid not initialized"); 289 291 EventableDescriptor *ed = dynamic_cast <EventableDescriptor*> (Bindable_t::GetObject (binding)); 290 292 if (ed) { 291 293 return ed->GetSubprocessPid (pid) ? 1 : 0; … … 318 320 extern "C" void evma_signal_loopbreak() 319 321 { 320 322 if (!EventMachine) 321 throw std::runtime_error (" not initialized");323 throw std::runtime_error ("evma_signal_loopbreak not initialized"); 322 324 EventMachine->SignalLoopBreaker(); 323 325 } 324 326 … … 331 333 extern "C" const char *evma__write_file (const char *filename) 332 334 { 333 335 if (!EventMachine) 334 throw std::runtime_error (" not initialized");336 throw std::runtime_error ("evma__write_file not initialized"); 335 337 return EventMachine->_OpenFileForWriting (filename); 336 338 } 337 339 … … 343 345 extern "C" int evma_get_comm_inactivity_timeout (const char *binding, int *value) 344 346 { 345 347 if (!EventMachine) 346 throw std::runtime_error (" not initialized");348 throw std::runtime_error ("evma_get_comm_inactivity_timeout not initialized"); 347 349 EventableDescriptor *ed = dynamic_cast <EventableDescriptor*> (Bindable_t::GetObject (binding)); 348 350 if (ed) { 349 351 return ed->GetCommInactivityTimeout (value); … … 352 354 return 0; //Perhaps this should be an exception. Access to an unknown binding. 353 355 } 354 356 357 358 355 359 /******************************** 356 360 evma_set_comm_inactivity_timeout 357 361 ********************************/ … … 359 363 extern "C" int evma_set_comm_inactivity_timeout (const char *binding, int *value) 360 364 { 361 365 if (!EventMachine) 362 throw std::runtime_error (" not initialized");366 throw std::runtime_error ("evma_set_comm_inactivity_timeout not initialized"); 363 367 EventableDescriptor *ed = dynamic_cast <EventableDescriptor*> (Bindable_t::GetObject (binding)); 364 368 if (ed) { 365 369 return ed->SetCommInactivityTimeout (value); … … 375 379 376 380 extern "C" void evma_set_timer_quantum (int interval) 377 381 { 378 if (!EventMachine)379 throw std::runtime_error ("not initialized");380 382 EventMachine->SetTimerQuantum (interval); 381 383 } 382 384 385 383 386 /************************ 384 387 evma_set_max_timer_count 385 388 ************************/ … … 410 413 extern "C" const char *evma_popen (char * const*cmd_strings) 411 414 { 412 415 if (!EventMachine) 413 throw std::runtime_error (" not initialized");416 throw std::runtime_error ("evma_popen not initialized"); 414 417 return EventMachine->Socketpair (cmd_strings); 415 418 } 416 419 … … 422 425 extern "C" int evma_get_outbound_data_size (const char *binding) 423 426 { 424 427 if (!EventMachine) 425 throw std::runtime_error (" not initialized");428 throw std::runtime_error ("evma_get_outbound_data_size not initialized"); 426 429 EventableDescriptor *ed = dynamic_cast <EventableDescriptor*> (Bindable_t::GetObject (binding)); 427 430 return ed ? ed->GetOutboundDataSize() : 0; 428 431 } … … 484 487 int r; 485 488 486 489 if (!EventMachine) 487 throw std::runtime_error(" not initialized");490 throw std::runtime_error("evma_send_file_data_to_connection not initialized"); 488 491 489 492 int Fd = open (filename, O_RDONLY); 490 493 -
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); … … 875 878 { 876 879 // TODO: This is something of a hack, or at least it's a static method of the wrong class. 877 880 AcceptorDescriptor *ad = dynamic_cast <AcceptorDescriptor*> (Bindable_t::GetObject (binding)); 881 878 882 if (ad) 879 883 ad->ScheduleClose (false); 880 884 else … … 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 -
ed.h
old new 61 61 62 62 void SetEventCallback (void (*cb)(const char*, int, const char*, int)); 63 63 64 virtual bool GetSockname (struct sockaddr*) {return false;} 64 65 virtual bool GetPeername (struct sockaddr*) {return false;} 65 virtual bool GetSockname (struct sockaddr*) {return false;}66 66 virtual bool GetSubprocessPid (pid_t*) {return false;} 67 67 68 68 virtual void StartTls() {}
