Index: src/OFSocket.h ================================================================== --- src/OFSocket.h +++ src/OFSocket.h @@ -21,15 +21,17 @@ */ @interface OFSocket: OFStream { @public #ifndef _WIN32 - int sock; + int sock; #else - SOCKET sock; + SOCKET sock; #endif - BOOL eos; + BOOL listening; +@protected + BOOL eos; } /** * \return A new autoreleased OFTCPSocket */ Index: src/OFSocketObserver.h ================================================================== --- src/OFSocketObserver.h +++ src/OFSocketObserver.h @@ -10,34 +10,40 @@ */ #import "OFObject.h" @class OFSocket; +@class OFTCPSocket; @class OFDataArray; @class OFMutableDictionary; /** * \brief A protocol that needs to be implemented by delegates for * OFSocketObserver. */ @protocol OFSocketObserverDelegate +/* + * This callback is called when a listening socket got a new incoming + * connection. + * + * \param sock The socket which did receive an incoming connection + */ +- (void)socketDidReceiveIncomingConnection: (OFTCPSocket*)sock; + /** * This callback is called when a socket did get ready for reading. * - * This callback is also called when a listening socket got a new incoming - * connection. - * - * \param sock The socket which did get ready for reading + * \param sock The socket which did become ready for reading */ -- (void)socketDidGetReadyForReading: (OFSocket*)sock; +- (void)socketDidBecomeReadyForReading: (OFSocket*)sock; /** * This callback is called when a socket did get ready for writing. * - * \param sock The socket which did get ready for writing + * \param sock The socket which did become ready for writing */ -- (void)socketDidGetReadyForWriting: (OFSocket*)sock; +- (void)socketDidBecomeReadyForWriting: (OFSocket*)sock; @end /** * \brief A class that can observe multiple sockets at once. */ @@ -67,10 +73,17 @@ * * \param delegate The delegate for the OFSocketObserver */ - (void)setDelegate: (OFObject *)delegate; +/** + * Adds a socket to observe for incoming connections. + * + * \param sock The socket to observe for incoming connections + */ +- (void)addSocketToObserveForIncomingConnections: (OFTCPSocket*)sock; + /** * Adds a socket to observe for reading. * * \param sock The socket to observe for reading */ @@ -81,10 +94,17 @@ * * \param sock The socket to observe for writing */ - (void)addSocketToObserveForWriting: (OFSocket*)sock; +/** + * Removes a socket to observe for incoming connections. + * + * \param sock The socket to remove from observing for incoming connections + */ +- (void)removeSocketToObserveForIncomingConnections: (OFTCPSocket*)sock; + /** * Removes a socket to observe for reading. * * \param sock The socket to remove from observing for reading */ Index: src/OFSocketObserver.m ================================================================== --- src/OFSocketObserver.m +++ src/OFSocketObserver.m @@ -15,10 +15,11 @@ #import "OFSocketObserver.h" #import "OFDataArray.h" #import "OFDictionary.h" #import "OFSocket.h" +#import "OFTCPSocket.h" #import "OFNumber.h" #import "OFAutoreleasePool.h" @implementation OFSocketObserver + socketObserver @@ -55,66 +56,45 @@ [delegate_ retain]; [delegate release]; delegate = delegate_; } -- (void)addSocketToObserveForReading: (OFSocket*)sock +- (void)_addSocket: (OFSocket*)sock + withEvents: (short)events { struct pollfd *fds_c = [fds cArray]; size_t i, count = [fds count]; BOOL found = NO; for (i = 0; i < count; i++) { if (fds_c[i].fd == sock->sock) { - fds_c[i].events |= POLLIN; + fds_c[i].events |= events; found = YES; } } if (!found) { OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init]; - struct pollfd p = { sock->sock, POLLIN, 0 }; + struct pollfd p = { sock->sock, events, 0 }; [fds addItem: &p]; [fdToSocket setObject: sock forKey: [OFNumber numberWithInt: sock->sock]]; [pool release]; } } -- (void)addSocketToObserveForWriting: (OFSocket*)sock -{ - struct pollfd *fds_c = [fds cArray]; - size_t i, nfds = [fds count]; - BOOL found = NO; - - for (i = 0; i < nfds; i++) { - if (fds_c[i].fd == sock->sock) { - fds_c[i].events |= POLLOUT; - found = YES; - } - } - - if (!found) { - OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init]; - struct pollfd p = { sock->sock, POLLOUT, 0 }; - [fds addItem: &p]; - [fdToSocket setObject: sock - forKey: [OFNumber numberWithInt: sock->sock]]; - [pool release]; - } -} - -- (void)removeSocketToObserveForReading: (OFSocket*)sock +- (void)_removeSocket: (OFSocket*)sock + withEvents: (short)events { struct pollfd *fds_c = [fds cArray]; size_t i, nfds = [fds count]; for (i = 0; i < nfds; i++) { if (fds_c[i].fd == sock->sock) { OFAutoreleasePool *pool; - fds_c[i].events &= ~POLLIN; + fds_c[i].events &= ~events; if (fds_c[i].events != 0) return; pool = [[OFAutoreleasePool alloc] init]; @@ -125,34 +105,45 @@ [pool release]; } } } + +- (void)addSocketToObserveForIncomingConnections: (OFTCPSocket*)sock +{ + [self _addSocket: sock + withEvents: POLLIN]; +} + +- (void)addSocketToObserveForReading: (OFSocket*)sock +{ + [self _addSocket: sock + withEvents: POLLIN]; +} + +- (void)addSocketToObserveForWriting: (OFSocket*)sock +{ + [self _addSocket: sock + withEvents: POLLOUT]; +} + +- (void)removeSocketToObserveForIncomingConnections: (OFTCPSocket*)sock +{ + [self _removeSocket: sock + withEvents: POLLIN]; +} + +- (void)removeSocketToObserveForReading: (OFSocket*)sock +{ + [self _removeSocket: sock + withEvents: POLLIN]; +} - (void)removeSocketToObserveForWriting: (OFSocket*)sock { - struct pollfd *fds_c = [fds cArray]; - size_t i, nfds = [fds count]; - - for (i = 0; i < nfds; i++) { - if (fds_c[i].fd == sock->sock) { - OFAutoreleasePool *pool; - - fds_c[i].events &= ~POLLOUT; - - if (fds_c[i].events != 0) - return; - - pool = [[OFAutoreleasePool alloc] init]; - - [fds removeItemAtIndex: i]; - [fdToSocket removeObjectForKey: - [OFNumber numberWithInt: sock->sock]]; - - [pool release]; - } - } + [self _removeSocket: sock + withEvents: POLLOUT]; } - (int)observe { return [self observeWithTimeout: -1]; @@ -173,17 +164,22 @@ OFSocket *sock; if (fds_c[i].revents & POLLIN) { num = [OFNumber numberWithInt: fds_c[i].fd]; sock = [fdToSocket objectForKey: num]; - [delegate socketDidGetReadyForReading: sock]; + + if (sock->listening) + [delegate socketDidReceiveIncomingConnection: + (OFTCPSocket*)sock]; + else + [delegate socketDidBecomeReadyForReading: sock]; } if (fds_c[i].revents & POLLOUT) { num = [OFNumber numberWithInt: fds_c[i].fd]; sock = [fdToSocket objectForKey: num]; - [delegate socketDidGetReadyForReading: sock]; + [delegate socketDidBecomeReadyForReading: sock]; } fds_c[i].revents = 0; } @@ -192,13 +188,17 @@ return ret; } @end @implementation OFObject (OFSocketObserverDelegate) -- (void)socketDidGetReadyForReading: (OFSocket*)sock +- (void)socketDidReceiveIncomingConnection: (OFTCPSocket*)sock +{ +} + +- (void)socketDidBecomeReadyForReading: (OFSocket*)sock { } -- (void)socketDidGetReadyForWriting: (OFSocket*)sock +- (void)socketDidBecomeReadyForWriting: (OFSocket*)sock { } @end Index: src/OFTCPSocket.m ================================================================== --- src/OFTCPSocket.m +++ src/OFTCPSocket.m @@ -312,10 +312,12 @@ @throw [OFNotConnectedException newWithClass: isa]; if (listen(sock, backlog) == -1) @throw [OFListenFailedException newWithClass: isa backLog: backlog]; + + listening = YES; } - (void)listen { if (sock == INVALID_SOCKET) @@ -322,10 +324,12 @@ @throw [OFNotConnectedException newWithClass: isa]; if (listen(sock, 5) == -1) @throw [OFListenFailedException newWithClass: isa backLog: 5]; + + listening = YES; } - (OFTCPSocket*)accept { OFTCPSocket *newsock; @@ -413,10 +417,12 @@ if (sock == INVALID_SOCKET) @throw [OFNotConnectedException newWithClass: isa]; close(sock); sock = INVALID_SOCKET; + listening = NO; + eos = NO; [self freeMemory: sockAddr]; sockAddr = NULL; sockAddrLen = 0; }