Changeset 373

Show
Ignore:
Timestamp:
06/07/07 17:29:09 (2 years ago)
Author:
blackhedd
Message:

supported epoll for datagram (UDP) descriptors.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • version_0/ext/ed.cpp

    r372 r373  
    289289        EpollEvent.events = (EPOLLIN | EPOLLOUT); 
    290290        assert (MyEventMachine); 
    291         MyEventMachine->_ModifyEpollEvent (this); 
     291        MyEventMachine->Modify (this); 
    292292        #endif 
    293293        return length; 
     
    570570                EpollEvent.events = (EPOLLIN | (SelectForWrite() ? EPOLLOUT : 0)); 
    571571                assert (MyEventMachine); 
    572                 MyEventMachine->_ModifyEpollEvent (this); 
     572                MyEventMachine->Modify (this); 
    573573                #endif 
    574574        } 
     
    861861{ 
    862862        memset (&ReturnAddress, 0, sizeof(ReturnAddress)); 
     863 
     864        #ifdef HAVE_EPOLL 
     865        EpollEvent.events = EPOLLIN; 
     866        #endif 
    863867} 
    864868 
     
    10061010                } 
    10071011        } 
     1012 
     1013        #ifdef HAVE_EPOLL 
     1014        EpollEvent.events = (EPOLLIN | (SelectForWrite() ? EPOLLOUT : 0)); 
     1015        assert (MyEventMachine); 
     1016        MyEventMachine->Modify (this); 
     1017        #endif 
    10081018} 
    10091019 
     
    10401050        OutboundPages.push_back (OutboundPage (buffer, length, ReturnAddress)); 
    10411051        OutboundDataSize += length; 
     1052        #ifdef HAVE_EPOLL 
     1053        EpollEvent.events = (EPOLLIN | EPOLLOUT); 
     1054        assert (MyEventMachine); 
     1055        MyEventMachine->Modify (this); 
     1056        #endif 
    10421057        return length; 
    10431058} 
     
    10881103        OutboundPages.push_back (OutboundPage (buffer, length, pin)); 
    10891104        OutboundDataSize += length; 
     1105        #ifdef HAVE_EPOLL 
     1106        EpollEvent.events = (EPOLLIN | EPOLLOUT); 
     1107        assert (MyEventMachine); 
     1108        MyEventMachine->Modify (this); 
     1109        #endif 
    10901110        return length; 
    10911111} 
  • version_0/ext/em.cpp

    r372 r373  
    311311                if (!_RunTimers()) 
    312312                        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                 */ 
    313318                _AddNewDescriptors(); 
     319                _ModifyDescriptors(); 
     320 
    314321                if (!_RunOnce()) 
    315322                        break; 
     
    390397                                } 
    391398 
     399                                ModifiedDescriptors.erase (ed); 
    392400                                delete ed; 
    393401                        } 
     
    11221130 
    11231131 
     1132/********************************** 
     1133EventMachine_t::_ModifyDescriptors 
     1134**********************************/ 
     1135 
     1136void 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/********************** 
     1171EventMachine_t::Modify 
     1172**********************/ 
     1173 
     1174void EventMachine_t::Modify (EventableDescriptor *ed) 
     1175{ 
     1176        if (!ed) 
     1177                throw std::runtime_error ("modified bad descriptor"); 
     1178        ModifiedDescriptors.insert (ed); 
     1179} 
     1180 
     1181 
    11241182/*********************************** 
    11251183EventMachine_t::_OpenFileForWriting 
  • version_0/ext/em.h

    r372 r373  
    7474 
    7575                void Add (EventableDescriptor*); 
     76                void Modify (EventableDescriptor*); 
    7677 
    7778                void SetTimerQuantum (int); 
     
    8182                // Temporary: 
    8283                void _UseEpoll(); 
    83                 void _ModifyEpollEvent (EventableDescriptor*); 
    8484 
    8585                /* 
     
    100100                bool _RunTimers(); 
    101101                void _AddNewDescriptors(); 
     102                void _ModifyDescriptors(); 
    102103                void _InitializeLoopBreaker(); 
    103104 
    104105                bool _RunSelectOnce(); 
    105106                bool _RunEpollOnce(); 
     107 
     108                void _ModifyEpollEvent (EventableDescriptor*); 
    106109 
    107110        public: 
     
    122125                vector<EventableDescriptor*> Descriptors; 
    123126                vector<EventableDescriptor*> NewDescriptors; 
     127                set<EventableDescriptor*> ModifiedDescriptors; 
    124128 
    125129                time_t NextHeartbeatTime; 
  • version_0/ext/project.h

    r363 r373  
    2929#include <iostream> 
    3030#include <map> 
     31#include <set> 
    3132#include <vector> 
    3233#include <deque> 
  • version_0/lib/eventmachine.rb

    r360 r373  
    699699        # then see Connection#send_datagram. 
    700700        # 
     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        # 
    701707        #-- 
    702708        # Replaced the implementation on 01Oct06. Thanks to Tobias Gustafsson for pointing 
  • version_0/tests/test_epoll.rb

    r372 r373  
    2424# 
    2525# 
     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. 
    2629# 
    2730 
     
    103106        end 
    104107 
     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 
    105136end