Changeset 373
- Timestamp:
- 06/07/07 17:29:09 (2 years ago)
- Files:
-
- version_0/ext/ed.cpp (modified) (6 diffs)
- version_0/ext/em.cpp (modified) (3 diffs)
- version_0/ext/em.h (modified) (4 diffs)
- version_0/ext/project.h (modified) (1 diff)
- version_0/lib/eventmachine.rb (modified) (1 diff)
- version_0/tests/test_epoll.rb (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
version_0/ext/ed.cpp
r372 r373 289 289 EpollEvent.events = (EPOLLIN | EPOLLOUT); 290 290 assert (MyEventMachine); 291 MyEventMachine-> _ModifyEpollEvent(this);291 MyEventMachine->Modify (this); 292 292 #endif 293 293 return length; … … 570 570 EpollEvent.events = (EPOLLIN | (SelectForWrite() ? EPOLLOUT : 0)); 571 571 assert (MyEventMachine); 572 MyEventMachine-> _ModifyEpollEvent(this);572 MyEventMachine->Modify (this); 573 573 #endif 574 574 } … … 861 861 { 862 862 memset (&ReturnAddress, 0, sizeof(ReturnAddress)); 863 864 #ifdef HAVE_EPOLL 865 EpollEvent.events = EPOLLIN; 866 #endif 863 867 } 864 868 … … 1006 1010 } 1007 1011 } 1012 1013 #ifdef HAVE_EPOLL 1014 EpollEvent.events = (EPOLLIN | (SelectForWrite() ? EPOLLOUT : 0)); 1015 assert (MyEventMachine); 1016 MyEventMachine->Modify (this); 1017 #endif 1008 1018 } 1009 1019 … … 1040 1050 OutboundPages.push_back (OutboundPage (buffer, length, ReturnAddress)); 1041 1051 OutboundDataSize += length; 1052 #ifdef HAVE_EPOLL 1053 EpollEvent.events = (EPOLLIN | EPOLLOUT); 1054 assert (MyEventMachine); 1055 MyEventMachine->Modify (this); 1056 #endif 1042 1057 return length; 1043 1058 } … … 1088 1103 OutboundPages.push_back (OutboundPage (buffer, length, pin)); 1089 1104 OutboundDataSize += length; 1105 #ifdef HAVE_EPOLL 1106 EpollEvent.events = (EPOLLIN | EPOLLOUT); 1107 assert (MyEventMachine); 1108 MyEventMachine->Modify (this); 1109 #endif 1090 1110 return length; 1091 1111 } version_0/ext/em.cpp
r372 r373 311 311 if (!_RunTimers()) 312 312 break; 313 314 /* _Add must precede _Modify because the same descriptor might 315 * be on both lists during the same pass through the machine, 316 * and to modify a descriptor before adding it would fail. 317 */ 313 318 _AddNewDescriptors(); 319 _ModifyDescriptors(); 320 314 321 if (!_RunOnce()) 315 322 break; … … 390 397 } 391 398 399 ModifiedDescriptors.erase (ed); 392 400 delete ed; 393 401 } … … 1122 1130 1123 1131 1132 /********************************** 1133 EventMachine_t::_ModifyDescriptors 1134 **********************************/ 1135 1136 void EventMachine_t::_ModifyDescriptors() 1137 { 1138 /* For implementations which don't level check every descriptor on 1139 * every pass through the machine, as select does. 1140 * If we're not selecting, then descriptors need a way to signal to the 1141 * machine that their readable or writable status has changed. 1142 * That's what the ::Modify call is for. We do it this way to avoid 1143 * modifying descriptors during the loop traversal, where it can easily 1144 * happen that an object (like a UDP socket) gets data written on it by 1145 * the application during #post_init. That would take place BEFORE the 1146 * descriptor even gets added to the epoll descriptor, so the modify 1147 * operation will crash messily. 1148 * Another really messy possibility is for a descriptor to put itself 1149 * on the Modified list, and then get deleted before we get here. 1150 * Remember, deletes happen after the I/O traversal and before the 1151 * next pass through here. So we have to make sure when we delete a 1152 * descriptor to remove it from the Modified list. 1153 */ 1154 1155 #ifdef HAVE_EPOLL 1156 if (bEpoll) { 1157 set<EventableDescriptor*>::iterator i = ModifiedDescriptors.begin(); 1158 while (i != ModifiedDescriptors.end()) { 1159 assert (*i); 1160 _ModifyEpollEvent (*i); 1161 ++i; 1162 } 1163 } 1164 #endif 1165 1166 ModifiedDescriptors.clear(); 1167 } 1168 1169 1170 /********************** 1171 EventMachine_t::Modify 1172 **********************/ 1173 1174 void EventMachine_t::Modify (EventableDescriptor *ed) 1175 { 1176 if (!ed) 1177 throw std::runtime_error ("modified bad descriptor"); 1178 ModifiedDescriptors.insert (ed); 1179 } 1180 1181 1124 1182 /*********************************** 1125 1183 EventMachine_t::_OpenFileForWriting version_0/ext/em.h
r372 r373 74 74 75 75 void Add (EventableDescriptor*); 76 void Modify (EventableDescriptor*); 76 77 77 78 void SetTimerQuantum (int); … … 81 82 // Temporary: 82 83 void _UseEpoll(); 83 void _ModifyEpollEvent (EventableDescriptor*);84 84 85 85 /* … … 100 100 bool _RunTimers(); 101 101 void _AddNewDescriptors(); 102 void _ModifyDescriptors(); 102 103 void _InitializeLoopBreaker(); 103 104 104 105 bool _RunSelectOnce(); 105 106 bool _RunEpollOnce(); 107 108 void _ModifyEpollEvent (EventableDescriptor*); 106 109 107 110 public: … … 122 125 vector<EventableDescriptor*> Descriptors; 123 126 vector<EventableDescriptor*> NewDescriptors; 127 set<EventableDescriptor*> ModifiedDescriptors; 124 128 125 129 time_t NextHeartbeatTime; version_0/ext/project.h
r363 r373 29 29 #include <iostream> 30 30 #include <map> 31 #include <set> 31 32 #include <vector> 32 33 #include <deque> version_0/lib/eventmachine.rb
r360 r373 699 699 # then see Connection#send_datagram. 700 700 # 701 # DO NOT call send_data from a datagram socket 702 # outside of a #receive_data method. Use #send_datagram. If you do use #send_data 703 # outside of a #receive_data method, you'll get a confusing error 704 # because there is no "peer," as #send_data requires. (Inside of #receive_data, 705 # #send_data "fakes" the peer as described above.) 706 # 701 707 #-- 702 708 # Replaced the implementation on 01Oct06. Thanks to Tobias Gustafsson for pointing version_0/tests/test_epoll.rb
r372 r373 24 24 # 25 25 # 26 # TODO, and I know this doesn't belong here, but if a datagram calls 27 # send_data outside of a receive_data, there is no return address, and 28 # the result is a very confusing error message. 26 29 # 27 30 … … 103 106 end 104 107 108 109 module TestDatagramServer 110 def receive_data dgm 111 $in = dgm 112 send_data "abcdefghij" 113 end 114 end 115 module TestDatagramClient 116 def post_init 117 send_datagram "1234567890", "127.0.0.1", 9500 118 end 119 def receive_data dgm 120 $out = dgm 121 EM.stop 122 end 123 end 124 125 def test_datagrams 126 $in = $out = "" 127 EM.epoll 128 EM.run { 129 EM.open_datagram_socket "127.0.0.1", 9500, TestDatagramServer 130 EM.open_datagram_socket "127.0.0.1", 0, TestDatagramClient 131 } 132 assert_equal( "1234567890", $in ) 133 assert_equal( "abcdefghij", $out ) 134 end 135 105 136 end
