Download Reference Manual
The Developer's Library for D
About Wiki Forums Source Search Contact

Changeset 3851

Show
Ignore:
Timestamp:
08/04/08 16:24:57 (4 months ago)
Author:
schveiguy
Message:

Deprecating ISelector.reregister, call register instead.
Applied patch from rrichardson (thanks!)
Fixed some minor bugs

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/tango/io/selector/AbstractSelector.d

    r2983 r3851  
    3939 * manage will be incremented dynamically if necessary. 
    4040 * 
    41  * To add, modify or remove conduit registrations to the selector you use 
    42  * the register(), reregister() and unregister() methods respectively. 
     41 * To add or modify conduit registrations in the selector, use the register() 
     42 * method.  To remove conduit registrations from the selector, use the 
     43 * unregister() method. 
    4344 * 
    4445 * To wait for events from the conduits you need to call any of the select() 
     
    8788 *             { 
    8889 *                 Stdout.format("Received '{0}' from peer\n", buffer[0..count]); 
    89  *                 selector.reregister(key.conduit, Event.Write, key.attachment); 
     90 *                 selector.register(key.conduit, Event.Write, key.attachment); 
    9091 *             } 
    9192 *             else 
     
    102103 *             { 
    103104 *                 Stdout("Sent 'MESSAGE' to peer\n"); 
    104  *                 selector.reregister(key.conduit, Event.Read, key.attachment); 
     105 *                 selector.register(key.conduit, Event.Read, key.attachment); 
    105106 *             } 
    106107 *             else 
     
    193194 
    194195    /** 
    195      * Modify the events that are being tracked or the 'attachment' field 
    196      * for an already registered conduit. 
    197      * 
    198      * Params: 
    199      * conduit      = conduit that will be associated to the selector 
    200      * events       = bit mask of Event values that represent the events that 
    201      *                will be tracked for the conduit. 
    202      * attachment   = optional object with application-specific data that will 
    203      *                be available when an event is triggered for the conduit 
    204      * 
    205      * Remarks: 
    206      * The 'attachment' member of the SelectionKey will always be overwritten, 
    207      * even if it's null. 
    208      * 
    209      * Examples: 
    210      * --- 
    211      * AbstractSelector selector; 
    212      * SocketConduit conduit; 
    213      * MyClass object; 
    214      * 
    215      * selector.reregister(conduit, Event.Write, object); 
    216      * --- 
    217      */ 
    218     public abstract void reregister(ISelectable conduit, Event events, 
    219                                     Object attachment); 
     196     * Deprecated, use register instead 
     197     */ 
     198    deprecated public final void reregister(ISelectable conduit, Event events, 
     199            Object attachment = null) 
     200    { 
     201        register(conduit, events, attachment); 
     202    } 
    220203 
    221204    /** 
  • trunk/tango/io/selector/EpollSelector.d

    r3508 r3851  
    6767     *             { 
    6868     *                 Stdout.format("Received '{0}' from peer\n", buffer[0..count]); 
    69      *                 selector.reregister(key.conduit, Event.Write, key.attachment); 
     69     *                 selector.register(key.conduit, Event.Write, key.attachment); 
    7070     *             } 
    7171     *             else 
     
    8282     *             { 
    8383     *                 Stdout("Sent 'MESSAGE' to peer"); 
    84      *                 selector.reregister(key.conduit, Event.Read, key.attachment); 
     84     *                 selector.register(key.conduit, Event.Read, key.attachment); 
    8585     *             } 
    8686     *             else 
     
    196196        /** 
    197197         * Associate a conduit to the selector and track specific I/O events. 
     198         * If a conduit is already associated, changes the events and 
     199         * attachment. 
    198200         * 
    199201         * Params: 
     
    223225        body 
    224226        { 
    225             epoll_event     event; 
    226             SelectionKey    key = new SelectionKey(conduit, events, attachment); 
    227  
    228             event.events = events; 
    229             // We associate the selection key to the epoll_event to be able to 
    230             // retrieve it efficiently when we get events for this handle. 
    231             event.data.ptr = cast(void*) key; 
    232  
    233             if (epoll_ctl(_epfd, EPOLL_CTL_ADD, conduit.fileHandle(), &event) == 0) 
    234             { 
    235                 // We keep the keys in a map to make sure that the key is not 
    236                 // garbage collected while there is still a reference to it in 
    237                 // an epoll_event. This also allows to to efficiently find the 
    238                 // key corresponding to a handle in methods where this 
    239                 // association is not provided automatically. 
    240                 _keys[conduit.fileHandle()] = key; 
    241             } 
    242             else 
    243             { 
    244                 checkErrno(__FILE__, __LINE__); 
    245             } 
    246         } 
    247  
    248         /** 
    249          * Modify the events that are being tracked or the 'attachment' field 
    250          * for an already registered conduit. 
    251          * 
    252          * Params: 
    253          * conduit      = conduit that will be associated to the selector; 
    254          *                must be a valid conduit (i.e. not null and open). 
    255          * events       = bit mask of Event values that represent the events 
    256          *                that will be tracked for the conduit. 
    257          * attachment   = optional object with application-specific data that 
    258          *                will be available when an event is triggered for the 
    259          *                conduit 
    260          * 
    261          * Remarks: 
    262          * The 'attachment' member of the SelectionKey will always be 
    263          * overwritten, even if it's null. 
    264          * 
    265          * Throws: 
    266          * UnregisteredConduitException if the conduit had not been previously 
    267          * registered to the selector; SelectorException if there are not 
    268          * enough resources to modify the conduit registration. 
    269          * 
    270          * Examples: 
    271          * --- 
    272          * selector.reregister(conduit, Event.Write, object); 
    273          * --- 
    274          */ 
    275         public void reregister(ISelectable conduit, Event events, Object attachment = null) 
    276         in 
    277         { 
    278             assert(conduit !is null && conduit.fileHandle() >= 0); 
    279         } 
    280         body 
    281         { 
    282227            SelectionKey* key = (conduit.fileHandle() in _keys); 
    283228 
     
    299244            else 
    300245            { 
    301                 throw new UnregisteredConduitException(__FILE__, __LINE__); 
     246                epoll_event     event; 
     247                SelectionKey    newkey = new SelectionKey(conduit, events, attachment); 
     248 
     249                event.events = events; 
     250                // We associate the selection key to the epoll_event to be able to 
     251                // retrieve it efficiently when we get events for this handle. 
     252                event.data.ptr = cast(void*) newkey; 
     253 
     254                if (epoll_ctl(_epfd, EPOLL_CTL_ADD, conduit.fileHandle(), &event) == 0) 
     255                { 
     256                    // We keep the keys in a map to make sure that the key is not 
     257                    // garbage collected while there is still a reference to it in 
     258                    // an epoll_event. This also allows to to efficiently find the 
     259                    // key corresponding to a handle in methods where this 
     260                    // association is not provided automatically. 
     261                    _keys[conduit.fileHandle()] = newkey; 
     262                } 
     263                else 
     264                { 
     265                    checkErrno(__FILE__, __LINE__); 
     266                } 
    302267            } 
    303268        } 
  • trunk/tango/io/selector/PollSelector.d

    r3508 r3851  
    121121        /** 
    122122         * Associate a conduit to the selector and track specific I/O events. 
     123         * If a conduit is already associated, modify the events and 
     124         * attachment. 
    123125         * 
    124126         * Params: 
     
    148150        { 
    149151            debug (selector) 
    150                 Stdout.format("--- PollSelector.register(handle={0}, events=0x{1:x})\n", 
    151                               cast(int) conduit.fileHandle(), cast(uint) events); 
    152  
    153             // We make sure that the conduit is not already registered to 
    154             // the Selector 
    155             if ((conduit.fileHandle() in _keys) is null) 
    156             { 
    157                 if (_count == _pfds.length) 
    158                     _pfds.length = _pfds.length + 1; 
    159  
    160                 _pfds[_count].fd = conduit.fileHandle(); 
    161                 _pfds[_count].events = cast(short) events; 
    162                 _pfds[_count].revents = 0; 
    163  
    164                 _keys[conduit.fileHandle()] = new PollSelectionKey(conduit, events, _count, attachment); 
    165                 _count++; 
    166             } 
    167             else 
    168             { 
    169                 throw new RegisteredConduitException(__FILE__, __LINE__); 
    170             } 
    171         } 
    172  
    173         /** 
    174          * Modify the events that are being tracked or the 'attachment' field 
    175          * for an already registered conduit. 
    176          * 
    177          * Params: 
    178          * conduit      = conduit that will be associated to the selector; 
    179          *                must be a valid conduit (i.e. not null and open). 
    180          * events       = bit mask of Event values that represent the events 
    181          *                that will be tracked for the conduit. 
    182          * attachment   = optional object with application-specific data that 
    183          *                will be available when an event is triggered for the 
    184          *                conduit 
    185          * 
    186          * Remarks: 
    187          * The 'attachment' member of the SelectionKey will always be 
    188          * overwritten, even if it's null. 
    189          * 
    190          * Throws: 
    191          * UnregisteredConduitException if the conduit had not been previously 
    192          * registered to the selector. 
    193          * 
    194          * Examples: 
    195          * --- 
    196          * selector.reregister(conduit, Event.Write, object); 
    197          * --- 
    198          */ 
    199         public void reregister(ISelectable conduit, Event events, Object attachment = null) 
    200         in 
    201         { 
    202             assert(conduit !is null && conduit.fileHandle() >= 0); 
    203         } 
    204         body 
    205         { 
    206             debug (selector) 
    207                 Stdout.format("--- PollSelector.reregister(handle={0}, events=0x{1:x})", 
     152                Stdout.formatln("--- PollSelector.register(handle={0}, events=0x{1:x})", 
    208153                              cast(int) conduit.fileHandle(), cast(uint) events); 
    209154 
     
    213158            { 
    214159                debug (selector) 
    215                     Stdout.format("--- Adding pollfd in index {0} (of {1})\n", 
     160                    Stdout.formatln("--- Adding pollfd in index {0} (of {1})", 
    216161                                  current.index, _count); 
    217162 
     
    223168            else 
    224169            { 
    225                 throw new UnregisteredConduitException(__FILE__, __LINE__); 
     170                if (_count == _pfds.length) 
     171                    _pfds.length = _pfds.length + 1; 
     172 
     173                _pfds[_count].fd = conduit.fileHandle(); 
     174                _pfds[_count].events = cast(short) events; 
     175                _pfds[_count].revents = 0; 
     176 
     177                _keys[conduit.fileHandle()] = new PollSelectionKey(conduit, events, _count, attachment); 
     178                _count++; 
    226179            } 
    227180        } 
     
    249202                { 
    250203                    debug (selector) 
    251                         Stdout.format("--- PollSelector.unregister(handle={0})\n", 
     204                        Stdout.formatln("--- PollSelector.unregister(handle={0})", 
    252205                                      cast(int) conduit.fileHandle()); 
    253206 
     
    257210                    { 
    258211                        debug (selector) 
    259                             Stdout.format("--- Removing pollfd in index {0} (of {1})\n", 
     212                            Stdout.formatln("--- Removing pollfd in index {0} (of {1})", 
    260213                                          removed.index, _count); 
    261214 
    262                         for (uint i = removed.index + 1; i > 0 && i < _count; i++) 
    263                         { 
    264                             _pfds[i - 1] = _pfds[i]; 
    265                         } 
     215                        // 
     216                        // instead of doing an O(n) remove, move the last 
     217                        // element to the removed slot 
     218                        // 
     219                        _pfds[removed.index] = _pfds[_count - 1]; 
     220                        _keys[cast(ISelectable.Handle)_pfds[removed.index].fd].index = removed.index; 
    266221                        _count--; 
    267222 
     
    271226                    { 
    272227                        debug (selector) 
    273                             Stdout.format("--- PollSelector.unregister(handle={0}): conduit was not found\n", 
     228                            Stdout.formatln("--- PollSelector.unregister(handle={0}): conduit was not found", 
    274229                                          cast(int) conduit.fileHandle()); 
    275230                        throw new UnregisteredConduitException(__FILE__, __LINE__); 
     
    279234                { 
    280235                    debug (selector) 
    281                         Stdout.format("--- Exception inside PollSelector.unregister(handle={0}): {1}", 
     236                        Stdout.formatln("--- Exception inside PollSelector.unregister(handle={0}): {1}", 
    282237                                      cast(int) conduit.fileHandle(), e.toString()); 
    283238 
     
    314269 
    315270            debug (selector) 
    316                 Stdout.format("--- PollSelector.select({0} ms): waiting on {1} handles\n", 
     271                Stdout.formatln("--- PollSelector.select({0} ms): waiting on {1} handles", 
    317272                              to, _count); 
    318273 
     
    340295                            { 
    341296                                debug (selector) 
    342                                     Stdout.format("--- Found events 0x{0:x} for handle {1} (index {2})\n", 
     297                                    Stdout.formatln("--- Found events 0x{0:x} for handle {1} (index {2})", 
    343298                                                  cast(uint) pfd.revents, cast(int) pfd.fd, i); 
    344299 
     
    364319                                { 
    365320                                    debug (selector) 
    366                                         Stdout.format("--- Handle {0} was not found in the Selector\n", 
     321                                        Stdout.formatln("--- Handle {0} was not found in the Selector", 
    367322                                                      cast(int) pfd.fd); 
    368323                                } 
  • trunk/tango/io/selector/SelectSelector.d

    r3508 r3851  
    153153    } 
    154154 
     155    private HandleSet allocateSet(ref HandleSet set, ref HandleSet selectedSet) 
     156    { 
     157        if(set is null) 
     158        { 
     159            set = new HandleSet(_size); 
     160            selectedSet = new HandleSet(_size); 
     161        } 
     162        return set; 
     163    } 
     164 
    155165    /** 
    156166     * Associate a conduit to the selector and track specific I/O events. 
     167     * If a conduit is already associated with the selector, the events and 
     168     * attachment are upated. 
    157169     * 
    158170     * Params: 
     
    185197        debug (selector) 
    186198            Stdout.format("--- SelectSelector.register(handle={0}, events=0x{1:x})\n", 
    187                    cast(int) handle, cast(uint) events); 
    188  
    189         // We make sure that the conduit is not already registered to 
    190         // the Selector 
    191         SelectionKey* key = (conduit.fileHandle() in _keys); 
    192  
    193         if (key is null) 
     199                          cast(int) handle, cast(uint) events); 
     200 
     201        SelectionKey *key = (handle in _keys); 
     202        if (key !is null) 
     203        { 
     204            if ((events & Event.Read) || (events & Event.Hangup)) 
     205            { 
     206                allocateSet(_readSet, _selectedReadSet).set(handle); 
     207            } 
     208            else if (_readSet !is null) 
     209            { 
     210                _readSet.clear(handle); 
     211            } 
     212 
     213            if ((events & Event.Write)) 
     214            { 
     215                allocateSet(_writeSet, _selectedWriteSet).set(handle); 
     216            } 
     217            else if (_writeSet !is null) 
     218            { 
     219                _writeSet.clear(handle); 
     220            } 
     221 
     222            if (events & Event.Error) 
     223            { 
     224                allocateSet(_exceptionSet, _selectedExceptionSet).set(handle); 
     225            } 
     226            else if (_exceptionSet !is null) 
     227            { 
     228                _exceptionSet.clear(handle); 
     229            } 
     230 
     231            version (Posix) 
     232            { 
     233                if (handle > _maxfd) 
     234                    _maxfd = handle; 
     235            } 
     236 
     237            (*key).events = events; 
     238            (*key).attachment = attachment; 
     239        } 
     240        else 
    194241        { 
    195242            // Keep record of the Conduits for whom we're tracking events. 
     
    198245            if ((events & Event.Read) || (events & Event.Hangup)) 
    199246            { 
    200                 if (_readSet is null) 
    201                 { 
    202                     _readSet = new HandleSet(_size); 
    203                     _selectedReadSet = new HandleSet(_size); 
    204                 } 
    205                 _readSet.set(handle); 
     247                allocateSet(_readSet, _selectedReadSet).set(handle); 
    206248            } 
    207249 
    208250            if (events & Event.Write) 
    209251            { 
    210                 if (_writeSet is null) 
    211                 { 
    212                     _writeSet = new HandleSet(_size); 
    213                     _selectedWriteSet = new HandleSet(_size); 
    214                 } 
    215                 _writeSet.set(handle); 
     252                allocateSet(_writeSet, _selectedWriteSet).set(handle); 
    216253            } 
    217254 
    218255            if (events & Event.Error) 
    219256            { 
    220                 if (_exceptionSet is null) 
    221                 { 
    222                     _exceptionSet = new HandleSet(_size); 
    223                     _selectedExceptionSet = new HandleSet(_size); 
    224                 } 
    225                 _exceptionSet.set(handle); 
     257                allocateSet(_exceptionSet, _selectedExceptionSet).set(handle); 
    226258            } 
    227259 
     
    231263                    _maxfd = handle; 
    232264            } 
    233         } 
    234         else 
    235         { 
    236             throw new RegisteredConduitException(__FILE__, __LINE__); 
    237         } 
    238     } 
    239  
    240     /** 
    241      * Modify the events that are being tracked or the 'attachment' field 
    242      * for an already registered conduit. 
    243      * 
    244      * Params: 
    245      * conduit      = conduit that will be associated to the selector; 
    246      *                must be a valid conduit (i.e. not null and open). 
    247      * events       = bit mask of Event values that represent the events 
    248      *                that will be tracked for the conduit. 
    249      * attachment   = optional object with application-specific data that 
    250      *                will be available when an event is triggered for the 
    251      *                conduit 
    252      * 
    253      * Remarks: 
    254      * The 'attachment' member of the SelectionKey will always be 
    255      * overwritten, even if it's null. 
    256      * 
    257      * Throws: 
    258      * UnregisteredConduitException if the conduit had not been previously 
    259      * registered to the selector. 
    260      * 
    261      * Examples: 
    262      * --- 
    263      * selector.reregister(conduit, Event.Write, object); 
    264      * --- 
    265      */ 
    266     public void reregister(ISelectable conduit, Event events, Object attachment = null) 
    267     in 
    268     { 
    269         assert(conduit !is null && conduit.fileHandle() >= 0); 
    270     } 
    271     body 
    272     { 
    273         ISelectable.Handle handle = conduit.fileHandle(); 
    274  
    275         debug (selector) 
    276             Stdout.format("--- SelectSelector.reregister(handle={0}, events=0x{1:x})\n", 
    277                           cast(int) handle, cast(uint) events); 
    278  
    279         SelectionKey *key = (handle in _keys); 
    280         if (key !is null) 
    281         { 
    282             if ((events & Event.Read) || (events & Event.Hangup)) 
    283             { 
    284                 if (_readSet is null) 
    285                 { 
    286                     _readSet = new HandleSet(_size); 
    287                     _selectedReadSet = new HandleSet(_size); 
    288                 } 
    289                 _readSet.set(handle); 
    290             } 
    291             else if (_readSet !is null) 
    292             { 
    293                 _readSet.clear(handle); 
    294             } 
    295  
    296             if ((events & Event.Write)) 
    297             { 
    298                 if (_writeSet is null) 
    299                 { 
    300                     _writeSet = new HandleSet(_size); 
    301                     _selectedWriteSet = new HandleSet(_size); 
    302                 } 
    303                 _writeSet.set(handle); 
    304             } 
    305             else if (_writeSet !is null) 
    306             { 
    307                 _writeSet.clear(handle); 
    308             } 
    309  
    310             if (events & Event.Error) 
    311             { 
    312                 if (_exceptionSet is null) 
    313                 { 
    314                     _exceptionSet = new HandleSet(_size); 
    315                     _selectedExceptionSet = new HandleSet(_size); 
    316                 } 
    317                 _exceptionSet.set(handle); 
    318             } 
    319             else if (_exceptionSet !is null) 
    320             { 
    321                 _exceptionSet.clear(handle); 
    322             } 
    323  
    324             version (Posix) 
    325             { 
    326                 if (handle > _maxfd) 
    327                     _maxfd = handle; 
    328             } 
    329  
    330             (*key).events = events; 
    331             (*key).attachment = attachment; 
    332         } 
    333         else 
    334         { 
    335             throw new UnregisteredConduitException(__FILE__, __LINE__); 
    336265        } 
    337266    } 
  • trunk/tango/io/selector/model/ISelector.d

    r3069 r3851  
    3737 * conduit and the events that are to be tracked for it. The 'events' member 
    3838 * of the key can take two meanings, depending on where it's used. If used 
    39  * with the registration methods of the selector (register(), reregister()) it 
    40  * represents the events we want to track; if used within a foreach cycle 
    41  * on an ISelectionSet it represents the events that have been detected for a 
    42  * conduit. 
     39 * with the register() method of the selector it represents the events we want 
     40 * to track; if used within a foreach cycle on an ISelectionSet it represents 
     41 * the events that have been detected for a conduit. 
    4342 * 
    4443 * The SelectionKey can also hold an optional object via the 'attachment' 
     
    217216 * manage will be incremented dynamically if necessary. 
    218217 * 
    219  * To add, modify or remove conduit registrations to the selector you use 
    220  * the register(), reregister() and unregister() methods respectively. 
     218 * To add or modify conduit registrations in the selector, use the register() 
     219 * method.  To remove conduit registrations from the selector, use the 
     220 * unregister() method. 
    221221 * 
    222222 * To wait for events from the conduits you need to call any of the select() 
     
    263263 *             { 
    264264 *                 Stdout.format("Received '{0}' from peer\n", buffer[0..count]); 
    265  *                 selector.reregister(key.conduit, Event.Write, key.attachment); 
     265 *                 selector.register(key.conduit, Event.Write, key.attachment); 
    266266 *             } 
    267267 *             else 
     
    278278 *             { 
    279279 *                 Stdout.print("Sent 'MESSAGE' to peer\n"); 
    280  *                 selector.reregister(key.conduit, Event.Read, key.attachment); 
     280 *                 selector.register(key.conduit, Event.Read, key.attachment); 
    281281 *             } 
    282282 *             else 
     
    325325    /** 
    326326     * Associate a conduit to the selector and track specific I/O events. 
     327     * If the conduit is already part of the selector, modify the events or 
     328     * atachment. 
    327329     * 
    328330     * Params: 
     
    346348                                  Object attachment = null); 
    347349 
    348     /** 
    349      * Modify the events that are being tracked or the 'attachment' field 
    350      * for an already registered conduit. 
    351      * 
    352      * Params: 
    353      * conduit      = conduit that will be associated to the selector; 
    354      *                must be a valid conduit (i.e. not null and open). 
    355      * events       = bit mask of Event values that represent the events that 
    356      *                will be tracked for the conduit. 
    357      * attachment   = optional object with application-specific data that will 
    358      *                be available when an event is triggered for the conduit 
    359      * 
    360      * Remarks: 
    361      * The 'attachment' member of the SelectionKey will always be overwritten, 
    362      * even if it's null. 
    363      * 
    364      * Examples: 
    365      * --- 
    366      * ISelector selector; 
    367      * SocketConduit conduit; 
    368      * MyClass object; 
    369      * 
    370      * selector.reregister(conduit, Event.Write, object); 
    371      * --- 
    372      */ 
    373     public abstract void reregister(ISelectable conduit, Event events, 
    374                                     Object attachment = null); 
     350 
     351    /** 
     352     * Deprecated, use register instead 
     353     */ 
     354    deprecated public abstract void reregister(ISelectable conduit, Event 
     355            events, Object attachment = null); 
     356 
    375357    /** 
    376358     * Remove a conduit from the selector. 
     
    385367     */ 
    386368    public abstract void unregister(ISelectable conduit); 
     369 
    387370 
    388371    /**