Index: ObjFW.xcodeproj/project.pbxproj ================================================================== --- ObjFW.xcodeproj/project.pbxproj +++ ObjFW.xcodeproj/project.pbxproj @@ -103,14 +103,10 @@ 4B2B3E82140D430500EC2F7C /* OFMutableArray_adjacent.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B2B3E78140D430500EC2F7C /* OFMutableArray_adjacent.m */; }; 4B2B3E83140D430500EC2F7C /* OFMutableDictionary_hashtable.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B2B3E79140D430500EC2F7C /* OFMutableDictionary_hashtable.h */; settings = {ATTRIBUTES = (); }; }; 4B2B3E84140D430500EC2F7C /* OFMutableDictionary_hashtable.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B2B3E7A140D430500EC2F7C /* OFMutableDictionary_hashtable.m */; }; 4B2B3E85140D430500EC2F7C /* OFSOCKS5Socket.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B2B3E7B140D430500EC2F7C /* OFSOCKS5Socket.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4B2B3E86140D430500EC2F7C /* OFSOCKS5Socket.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B2B3E7C140D430500EC2F7C /* OFSOCKS5Socket.m */; }; - 4B355E6B141BF79500FAAA6F /* OFStreamPollObserver.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B355E67141BF79500FAAA6F /* OFStreamPollObserver.h */; }; - 4B355E6C141BF79500FAAA6F /* OFStreamPollObserver.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B355E68141BF79500FAAA6F /* OFStreamPollObserver.m */; }; - 4B355E6D141BF79500FAAA6F /* OFStreamSelectObserver.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B355E69141BF79500FAAA6F /* OFStreamSelectObserver.h */; }; - 4B355E6E141BF79500FAAA6F /* OFStreamSelectObserver.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B355E6A141BF79500FAAA6F /* OFStreamSelectObserver.m */; }; 4B39844213D3A24600E6F825 /* OFSet.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B39844013D3A24600E6F825 /* OFSet.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4B39844313D3A24600E6F825 /* OFSet.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B39844113D3A24600E6F825 /* OFSet.m */; }; 4B39844713D3AFB400E6F825 /* OFMutableSet.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B39844513D3AFB400E6F825 /* OFMutableSet.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4B39844813D3AFB400E6F825 /* OFMutableSet.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B39844613D3AFB400E6F825 /* OFMutableSet.m */; }; 4B39844A13D3D03000E6F825 /* OFSet.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B39844913D3D03000E6F825 /* OFSet.m */; }; @@ -223,10 +219,14 @@ 4B55A113133AC24600B58A93 /* OFReadFailedException.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B55A10D133AC24500B58A93 /* OFReadFailedException.m */; }; 4B55A114133AC24600B58A93 /* OFReadOrWriteFailedException.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B55A10E133AC24500B58A93 /* OFReadOrWriteFailedException.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4B55A115133AC24600B58A93 /* OFReadOrWriteFailedException.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B55A10F133AC24500B58A93 /* OFReadOrWriteFailedException.m */; }; 4B55A116133AC24600B58A93 /* OFWriteFailedException.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B55A110133AC24500B58A93 /* OFWriteFailedException.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4B55A117133AC24600B58A93 /* OFWriteFailedException.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B55A111133AC24600B58A93 /* OFWriteFailedException.m */; }; + 4B64D6EF1425381E007BDFB1 /* OFStreamObserver_poll.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B64D6EB1425381E007BDFB1 /* OFStreamObserver_poll.h */; }; + 4B64D6F01425381E007BDFB1 /* OFStreamObserver_poll.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B64D6EC1425381E007BDFB1 /* OFStreamObserver_poll.m */; }; + 4B64D6F11425381E007BDFB1 /* OFStreamObserver_select.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B64D6ED1425381E007BDFB1 /* OFStreamObserver_select.h */; }; + 4B64D6F21425381E007BDFB1 /* OFStreamObserver_select.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B64D6EE1425381E007BDFB1 /* OFStreamObserver_select.m */; }; 4B6965E213A58B1B004F1C3A /* OFFloatMatrix.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B6965E013A58B1B004F1C3A /* OFFloatMatrix.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4B6965E313A58B1B004F1C3A /* OFFloatMatrix.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B6965E113A58B1B004F1C3A /* OFFloatMatrix.m */; }; 4B7FF3B0133CE6DE00000324 /* OFMutexStillLockedException.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B7FF3AE133CE6DE00000324 /* OFMutexStillLockedException.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4B7FF3B1133CE6DE00000324 /* OFMutexStillLockedException.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B7FF3AF133CE6DE00000324 /* OFMutexStillLockedException.m */; }; 4B7FF3B4133CED6200000324 /* OFConditionStillWaitingException.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B7FF3B2133CED6100000324 /* OFConditionStillWaitingException.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -449,14 +449,10 @@ 4B2B3E78140D430500EC2F7C /* OFMutableArray_adjacent.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = OFMutableArray_adjacent.m; path = src/OFMutableArray_adjacent.m; sourceTree = ""; }; 4B2B3E79140D430500EC2F7C /* OFMutableDictionary_hashtable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OFMutableDictionary_hashtable.h; path = src/OFMutableDictionary_hashtable.h; sourceTree = ""; }; 4B2B3E7A140D430500EC2F7C /* OFMutableDictionary_hashtable.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = OFMutableDictionary_hashtable.m; path = src/OFMutableDictionary_hashtable.m; sourceTree = ""; }; 4B2B3E7B140D430500EC2F7C /* OFSOCKS5Socket.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OFSOCKS5Socket.h; path = src/OFSOCKS5Socket.h; sourceTree = ""; }; 4B2B3E7C140D430500EC2F7C /* OFSOCKS5Socket.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = OFSOCKS5Socket.m; path = src/OFSOCKS5Socket.m; sourceTree = ""; }; - 4B355E67141BF79500FAAA6F /* OFStreamPollObserver.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OFStreamPollObserver.h; path = src/OFStreamPollObserver.h; sourceTree = ""; }; - 4B355E68141BF79500FAAA6F /* OFStreamPollObserver.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = OFStreamPollObserver.m; path = src/OFStreamPollObserver.m; sourceTree = ""; }; - 4B355E69141BF79500FAAA6F /* OFStreamSelectObserver.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OFStreamSelectObserver.h; path = src/OFStreamSelectObserver.h; sourceTree = ""; }; - 4B355E6A141BF79500FAAA6F /* OFStreamSelectObserver.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = OFStreamSelectObserver.m; path = src/OFStreamSelectObserver.m; sourceTree = ""; }; 4B39844013D3A24600E6F825 /* OFSet.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OFSet.h; path = src/OFSet.h; sourceTree = ""; }; 4B39844113D3A24600E6F825 /* OFSet.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = OFSet.m; path = src/OFSet.m; sourceTree = ""; }; 4B39844513D3AFB400E6F825 /* OFMutableSet.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OFMutableSet.h; path = src/OFMutableSet.h; sourceTree = ""; }; 4B39844613D3AFB400E6F825 /* OFMutableSet.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = OFMutableSet.m; path = src/OFMutableSet.m; sourceTree = ""; }; 4B39844913D3D03000E6F825 /* OFSet.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = OFSet.m; path = tests/OFSet.m; sourceTree = ""; }; @@ -487,10 +483,14 @@ 4B55A10D133AC24500B58A93 /* OFReadFailedException.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = OFReadFailedException.m; path = src/exceptions/OFReadFailedException.m; sourceTree = ""; }; 4B55A10E133AC24500B58A93 /* OFReadOrWriteFailedException.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OFReadOrWriteFailedException.h; path = src/exceptions/OFReadOrWriteFailedException.h; sourceTree = ""; }; 4B55A10F133AC24500B58A93 /* OFReadOrWriteFailedException.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = OFReadOrWriteFailedException.m; path = src/exceptions/OFReadOrWriteFailedException.m; sourceTree = ""; }; 4B55A110133AC24500B58A93 /* OFWriteFailedException.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OFWriteFailedException.h; path = src/exceptions/OFWriteFailedException.h; sourceTree = ""; }; 4B55A111133AC24600B58A93 /* OFWriteFailedException.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = OFWriteFailedException.m; path = src/exceptions/OFWriteFailedException.m; sourceTree = ""; }; + 4B64D6EB1425381E007BDFB1 /* OFStreamObserver_poll.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OFStreamObserver_poll.h; path = src/OFStreamObserver_poll.h; sourceTree = ""; }; + 4B64D6EC1425381E007BDFB1 /* OFStreamObserver_poll.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = OFStreamObserver_poll.m; path = src/OFStreamObserver_poll.m; sourceTree = ""; }; + 4B64D6ED1425381E007BDFB1 /* OFStreamObserver_select.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OFStreamObserver_select.h; path = src/OFStreamObserver_select.h; sourceTree = ""; }; + 4B64D6EE1425381E007BDFB1 /* OFStreamObserver_select.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = OFStreamObserver_select.m; path = src/OFStreamObserver_select.m; sourceTree = ""; }; 4B6799561099E7C50041064A /* asprintf.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = asprintf.h; path = src/asprintf.h; sourceTree = ""; }; 4B6799581099E7C50041064A /* objc_sync.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = objc_sync.m; path = src/objc_sync.m; sourceTree = ""; }; 4B67995A1099E7C50041064A /* OFArray.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OFArray.h; path = src/OFArray.h; sourceTree = ""; }; 4B67995B1099E7C50041064A /* OFArray.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = OFArray.m; path = src/OFArray.m; sourceTree = ""; }; 4B67995C1099E7C50041064A /* OFAutoreleasePool.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OFAutoreleasePool.h; path = src/OFAutoreleasePool.h; sourceTree = ""; }; @@ -938,14 +938,14 @@ 4B2B3E7C140D430500EC2F7C /* OFSOCKS5Socket.m */, 4B67997D1099E7C50041064A /* OFStream.h */, 4B67997E1099E7C50041064A /* OFStream.m */, 4BAF5F47123460C900F4E111 /* OFStreamObserver.h */, 4BAF5F48123460C900F4E111 /* OFStreamObserver.m */, - 4B355E67141BF79500FAAA6F /* OFStreamPollObserver.h */, - 4B355E68141BF79500FAAA6F /* OFStreamPollObserver.m */, - 4B355E69141BF79500FAAA6F /* OFStreamSelectObserver.h */, - 4B355E6A141BF79500FAAA6F /* OFStreamSelectObserver.m */, + 4B64D6EB1425381E007BDFB1 /* OFStreamObserver_poll.h */, + 4B64D6EC1425381E007BDFB1 /* OFStreamObserver_poll.m */, + 4B64D6ED1425381E007BDFB1 /* OFStreamObserver_select.h */, + 4B64D6EE1425381E007BDFB1 /* OFStreamObserver_select.m */, 4BAF5F49123460C900F4E111 /* OFStreamSocket.h */, 4BAF5F4A123460C900F4E111 /* OFStreamSocket.m */, 4B67997F1099E7C50041064A /* OFString.h */, 4B6799801099E7C50041064A /* OFString.m */, 4BF1BCC611C9663F0025511F /* OFString+Hashing.h */, @@ -1202,12 +1202,12 @@ 4B2B3E7F140D430500EC2F7C /* OFDictionary_hashtable.h in Headers */, 4B2B3E81140D430500EC2F7C /* OFMutableArray_adjacent.h in Headers */, 4B2B3E83140D430500EC2F7C /* OFMutableDictionary_hashtable.h in Headers */, 4BA85BCC140ECCE800E91D51 /* OFMutableSet_hashtable.h in Headers */, 4BA85BCE140ECCE800E91D51 /* OFSet_hashtable.h in Headers */, - 4B355E6B141BF79500FAAA6F /* OFStreamPollObserver.h in Headers */, - 4B355E6D141BF79500FAAA6F /* OFStreamSelectObserver.h in Headers */, + 4B64D6EF1425381E007BDFB1 /* OFStreamObserver_poll.h in Headers */, + 4B64D6F11425381E007BDFB1 /* OFStreamObserver_select.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXHeadersBuildPhase section */ @@ -1399,12 +1399,12 @@ 4BA85BCF140ECCE800E91D51 /* OFSet_hashtable.m in Sources */, 4B3D23A21337FC0D00DD29B8 /* OFSHA1Hash.m in Sources */, 4B2B3E86140D430500EC2F7C /* OFSOCKS5Socket.m in Sources */, 4B3D23A31337FC0D00DD29B8 /* OFStream.m in Sources */, 4B3D23A41337FC0D00DD29B8 /* OFStreamObserver.m in Sources */, - 4B355E6C141BF79500FAAA6F /* OFStreamPollObserver.m in Sources */, - 4B355E6E141BF79500FAAA6F /* OFStreamSelectObserver.m in Sources */, + 4B64D6F01425381E007BDFB1 /* OFStreamObserver_poll.m in Sources */, + 4B64D6F21425381E007BDFB1 /* OFStreamObserver_select.m in Sources */, 4B3D23A51337FC0D00DD29B8 /* OFStreamSocket.m in Sources */, 4B3D23A61337FC0D00DD29B8 /* OFString.m in Sources */, 4B3D23A71337FC0D00DD29B8 /* OFString+Hashing.m in Sources */, 4BB25E8B139C388A00F574EA /* OFString+Serialization.m in Sources */, 4B3D23A81337FC0D00DD29B8 /* OFString+URLEncoding.m in Sources */, Index: configure.ac ================================================================== --- configure.ac +++ configure.ac @@ -466,15 +466,15 @@ AC_DEFINE(HAVE_LOCALTIME_R, 1, [Whether we have localtime_r]) ]) AC_CHECK_HEADER(poll.h, [ AC_DEFINE(HAVE_POLL_H, 1, [Whether we have poll.h]) - AC_SUBST(OFSTREAMPOLLOBSERVER_M, "OFStreamPollObserver.m") + AC_SUBST(OFSTREAMOBSERVER_POLL_M, "OFStreamObserver_poll.m") ]) AC_CHECK_HEADERS(sys/select.h, [ AC_DEFINE(OF_HAVE_SYS_SELECT_H, 1, [Whether we have sys/select.h]) - AC_SUBST(OFSTREAMSELECTOBSERVER_M, "OFStreamSelectObserver.m") + AC_SUBST(OFSTREAMOBSERVER_SELECT_M, "OFStreamObserver_select.m") ]) AC_MSG_CHECKING(for getaddrinfo) AC_TRY_COMPILE([ #include Index: extra.mk.in ================================================================== --- extra.mk.in +++ extra.mk.in @@ -17,15 +17,15 @@ OBJC_PROPERTIES_M = @OBJC_PROPERTIES_M@ OBJC_SYNC_M = @OBJC_SYNC_M@ OFHTTPREQUESTTESTS_M = @OFHTTPREQUESTTESTS_M@ OFPLUGIN_M = @OFPLUGIN_M@ OFPLUGINTESTS_M = @OFPLUGINTESTS_M@ -OFSTREAMPOLLOBSERVER_M = @OFSTREAMPOLLOBSERVER_M@ -OFSTREAMSELECTOBSERVER_M = @OFSTREAMSELECTOBSERVER_M@ +OFSTREAMOBSERVER_POLL_M = @OFSTREAMOBSERVER_POLL_M@ +OFSTREAMOBSERVER_SELECT_M = @OFSTREAMOBSERVER_SELECT_M@ OFTHREAD_M = @OFTHREAD_M@ OFTHREADTESTS_M = @OFTHREADTESTS_M@ PROPERTIESTESTS_M = @PROPERTIESTESTS_M@ REEXPORT_LIBOBJC = @REEXPORT_LIBOBJC@ TESTPLUGIN = @TESTPLUGIN@ TESTS = @TESTS@ TEST_LAUNCHER = @TEST_LAUNCHER@ THREADING_H = @THREADING_H@ Index: src/Makefile ================================================================== --- src/Makefile +++ src/Makefile @@ -79,12 +79,12 @@ OFDictionary_hashtable.m \ OFMutableArray_adjacent.m \ OFMutableDictionary_hashtable.m \ OFMutableSet_hashtable.m \ OFSet_hashtable.m \ - ${OFSTREAMPOLLOBSERVER_M} \ - ${OFSTREAMSELECTOBSERVER_M} \ + ${OFSTREAMOBSERVER_POLL_M} \ + ${OFSTREAMOBSERVER_SELECT_M} \ ${ASPRINTF_M} \ ${FOUNDATION_COMPAT_M} \ iso_8859_15.m \ windows_1252.m \ ${OBJC_PROPERTIES_M} \ Index: src/OFStreamObserver.m ================================================================== --- src/OFStreamObserver.m +++ src/OFStreamObserver.m @@ -31,14 +31,14 @@ # import "OFTCPSocket.h" #endif #import "OFAutoreleasePool.h" #ifdef HAVE_POLL_H -# import "OFStreamPollObserver.h" +# import "OFStreamObserver_poll.h" #endif #if defined(HAVE_SYS_SELECT_H) || defined(_WIN32) -# import "OFStreamSelectObserver.h" +# import "OFStreamObserver_select.h" #endif #import "OFInitializationFailedException.h" #import "OFNotImplementedException.h" #import "OFOutOfRangeException.h" @@ -60,19 +60,19 @@ #if defined(HAVE_POLL_H) + alloc { if (self == [OFStreamObserver class]) - return [OFStreamPollObserver alloc]; + return [OFStreamObserver_poll alloc]; return [super alloc]; } #elif defined(HAVE_SYS_SELECT_H) || defined(_WIN32) + alloc { if (self == [OFStreamObserver class]) - return [OFStreamSelectObserver alloc]; + return [OFStreamObserver_select alloc]; return [super alloc]; } #endif ADDED src/OFStreamObserver_poll.h Index: src/OFStreamObserver_poll.h ================================================================== --- src/OFStreamObserver_poll.h +++ src/OFStreamObserver_poll.h @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2008, 2009, 2010, 2011 + * Jonathan Schleifer + * + * All rights reserved. + * + * This file is part of ObjFW. It may be distributed under the terms of the + * Q Public License 1.0, which can be found in the file LICENSE.QPL included in + * the packaging of this file. + * + * Alternatively, it may be distributed under the terms of the GNU General + * Public License, either version 2 or 3, which can be found in the file + * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this + * file. + */ + +#import "OFStreamObserver.h" + +@class OFDataArray; + +@interface OFStreamObserver_poll: OFStreamObserver +{ + OFDataArray *FDs; + OFMutableDictionary *FDToStream; +} +@end ADDED src/OFStreamObserver_poll.m Index: src/OFStreamObserver_poll.m ================================================================== --- src/OFStreamObserver_poll.m +++ src/OFStreamObserver_poll.m @@ -0,0 +1,238 @@ +/* + * Copyright (c) 2008, 2009, 2010, 2011 + * Jonathan Schleifer + * + * All rights reserved. + * + * This file is part of ObjFW. It may be distributed under the terms of the + * Q Public License 1.0, which can be found in the file LICENSE.QPL included in + * the packaging of this file. + * + * Alternatively, it may be distributed under the terms of the GNU General + * Public License, either version 2 or 3, which can be found in the file + * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this + * file. + */ + +#include "config.h" + +#define __NO_EXT_QNX + +#include +#include +#include + +#import "OFStreamObserver_poll.h" +#import "OFStream.h" +#import "OFArray.h" +#import "OFDictionary.h" +#import "OFDataArray.h" +#import "OFNumber.h" +#import "OFAutoreleasePool.h" + +#import "OFOutOfRangeException.h" + +enum { + QUEUE_ADD = 0, + QUEUE_REMOVE = 1, + QUEUE_READ = 0, + QUEUE_WRITE = 2 +}; + +@implementation OFStreamObserver_poll +- init +{ + self = [super init]; + + @try { + struct pollfd p = { 0, POLLIN, 0 }; + + FDs = [[OFDataArray alloc] initWithItemSize: + sizeof(struct pollfd)]; + FDToStream = [[OFMutableDictionary alloc] init]; + + p.fd = cancelFD[0]; + [FDs addItem: &p]; + } @catch (id e) { + [self release]; + @throw e; + } + + return self; +} + +- (void)dealloc +{ + [FDToStream release]; + [FDs release]; + + [super dealloc]; +} + + +- (void)_addStream: (OFStream*)stream + withEvents: (short)events +{ + struct pollfd *FDsCArray = [FDs cArray]; + size_t i, count = [FDs count]; + int fileDescriptor = [stream fileDescriptor]; + BOOL found = NO; + + for (i = 0; i < count; i++) { + if (FDsCArray[i].fd == fileDescriptor) { + FDsCArray[i].events |= events; + found = YES; + } + } + + if (!found) { + OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init]; + struct pollfd p = { fileDescriptor, events | POLLERR, 0 }; + [FDs addItem: &p]; + [FDToStream setObject: stream + forKey: [OFNumber numberWithInt: + fileDescriptor]]; + [pool release]; + } +} + +- (void)_removeStream: (OFStream*)stream + withEvents: (short)events +{ + struct pollfd *FDsCArray = [FDs cArray]; + size_t i, nFDs = [FDs count]; + int fileDescriptor = [stream fileDescriptor]; + + for (i = 0; i < nFDs; i++) { + if (FDsCArray[i].fd == fileDescriptor) { + OFAutoreleasePool *pool; + + FDsCArray[i].events &= ~events; + + if ((FDsCArray[i].events & ~POLLERR) != 0) + return; + + pool = [[OFAutoreleasePool alloc] init]; + + [FDs removeItemAtIndex: i]; + [FDToStream removeObjectForKey: + [OFNumber numberWithInt: fileDescriptor]]; + + [pool release]; + } + } +} + +- (void)_processQueue +{ + @synchronized (queue) { + OFStream **queueCArray = [queue cArray]; + OFNumber **queueInfoCArray = [queueInfo cArray]; + size_t i, count = [queue count]; + + for (i = 0; i < count; i++) { + switch ([queueInfoCArray[i] intValue]) { + case QUEUE_ADD | QUEUE_READ: + [readStreams addObject: queueCArray[i]]; + + [self _addStream: queueCArray[i] + withEvents: POLLIN]; + + break; + case QUEUE_ADD | QUEUE_WRITE: + [writeStreams addObject: queueCArray[i]]; + + [self _addStream: queueCArray[i] + withEvents: POLLOUT]; + + break; + case QUEUE_REMOVE | QUEUE_READ: + [readStreams removeObjectIdenticalTo: + queueCArray[i]]; + + [self _removeStream: queueCArray[i] + withEvents: POLLIN]; + + break; + case QUEUE_REMOVE | QUEUE_WRITE: + [writeStreams removeObjectIdenticalTo: + queueCArray[i]]; + + [self _removeStream: queueCArray[i] + withEvents: POLLOUT]; + + break; + default: + assert(0); + } + } + + [queue removeNObjects: count]; + [queueInfo removeNObjects: count]; + } +} + +- (BOOL)observeWithTimeout: (int)timeout +{ + OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init]; + struct pollfd *FDsCArray; + size_t i, nFDs; + + [self _processQueue]; + + if ([self _processCache]) + return YES; + + FDsCArray = [FDs cArray]; + nFDs = [FDs count]; + +#ifdef OPEN_MAX + if (nFDs > OPEN_MAX) + @throw [OFOutOfRangeException newWithClass: isa]; +#endif + + if (poll(FDsCArray, (nfds_t)nFDs, timeout) < 1) + return NO; + + for (i = 0; i < nFDs; i++) { + OFNumber *num; + OFStream *stream; + + if (FDsCArray[i].revents & POLLIN) { + if (FDsCArray[i].fd == cancelFD[0]) { + char buffer; + + assert(read(cancelFD[0], &buffer, 1) > 0); + FDsCArray[i].revents = 0; + + continue; + } + + num = [OFNumber numberWithInt: FDsCArray[i].fd]; + stream = [FDToStream objectForKey: num]; + [delegate streamDidBecomeReadyForReading: stream]; + [pool releaseObjects]; + } + + if (FDsCArray[i].revents & POLLOUT) { + num = [OFNumber numberWithInt: FDsCArray[i].fd]; + stream = [FDToStream objectForKey: num]; + [delegate streamDidBecomeReadyForReading: stream]; + [pool releaseObjects]; + } + + if (FDsCArray[i].revents & POLLERR) { + num = [OFNumber numberWithInt: FDsCArray[i].fd]; + stream = [FDToStream objectForKey: num]; + [delegate streamDidReceiveException: stream]; + [pool releaseObjects]; + } + + FDsCArray[i].revents = 0; + } + + [pool release]; + + return YES; +} +@end ADDED src/OFStreamObserver_select.h Index: src/OFStreamObserver_select.h ================================================================== --- src/OFStreamObserver_select.h +++ src/OFStreamObserver_select.h @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2008, 2009, 2010, 2011 + * Jonathan Schleifer + * + * All rights reserved. + * + * This file is part of ObjFW. It may be distributed under the terms of the + * Q Public License 1.0, which can be found in the file LICENSE.QPL included in + * the packaging of this file. + * + * Alternatively, it may be distributed under the terms of the GNU General + * Public License, either version 2 or 3, which can be found in the file + * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this + * file. + */ + +#ifdef OF_HAVE_SYS_SELECT_H +# include +#endif + +#import "OFStreamObserver.h" + +@interface OFStreamObserver_select: OFStreamObserver +{ + fd_set readFDs; + fd_set writeFDs; + fd_set exceptFDs; + int nFDs; +} +@end ADDED src/OFStreamObserver_select.m Index: src/OFStreamObserver_select.m ================================================================== --- src/OFStreamObserver_select.m +++ src/OFStreamObserver_select.m @@ -0,0 +1,219 @@ +/* + * Copyright (c) 2008, 2009, 2010, 2011 + * Jonathan Schleifer + * + * All rights reserved. + * + * This file is part of ObjFW. It may be distributed under the terms of the + * Q Public License 1.0, which can be found in the file LICENSE.QPL included in + * the packaging of this file. + * + * Alternatively, it may be distributed under the terms of the GNU General + * Public License, either version 2 or 3, which can be found in the file + * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this + * file. + */ + +#include "config.h" + +#define __NO_EXT_QNX + +#include +#include +#include + +#import "OFStreamObserver_select.h" +#import "OFStream.h" +#import "OFArray.h" +#import "OFNumber.h" +#import "OFAutoreleasePool.h" + +#ifdef _WIN32 +# define close(sock) closesocket(sock) +#endif + +enum { + QUEUE_ADD = 0, + QUEUE_REMOVE = 1, + QUEUE_READ = 0, + QUEUE_WRITE = 2 +}; + +@implementation OFStreamObserver_select +- init +{ + self = [super init]; + + FD_ZERO(&readFDs); + FD_ZERO(&writeFDs); + + FD_SET(cancelFD[0], &readFDs); + nFDs = cancelFD[0] + 1; + + return self; +} + +- (void)_addStream: (OFStream*)stream + withFDSet: (fd_set*)FDSet +{ + OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init]; + int fileDescriptor = [stream fileDescriptor]; + + FD_SET(fileDescriptor, FDSet); + FD_SET(fileDescriptor, &exceptFDs); + + if (fileDescriptor >= nFDs) + nFDs = fileDescriptor + 1; + + [pool release]; +} + +- (void)_removeStream: (OFStream*)stream + withFDSet: (fd_set*)FDSet + otherFDSet: (fd_set*)otherFDSet +{ + int fileDescriptor = [stream fileDescriptor]; + + FD_CLR(fileDescriptor, FDSet); + + if (!FD_ISSET(fileDescriptor, otherFDSet)) + FD_CLR(fileDescriptor, &exceptFDs); +} + +- (void)_processQueue +{ + @synchronized (queue) { + OFStream **queueCArray = [queue cArray]; + OFNumber **queueInfoCArray = [queueInfo cArray]; + size_t i, count = [queue count]; + + for (i = 0; i < count; i++) { + switch ([queueInfoCArray[i] intValue]) { + case QUEUE_ADD | QUEUE_READ: + [readStreams addObject: queueCArray[i]]; + + [self _addStream: queueCArray[i] + withFDSet: &readFDs]; + + break; + case QUEUE_ADD | QUEUE_WRITE: + [writeStreams addObject: queueCArray[i]]; + + [self _addStream: queueCArray[i] + withFDSet: &writeFDs]; + + break; + case QUEUE_REMOVE | QUEUE_READ: + [readStreams removeObjectIdenticalTo: + queueCArray[i]]; + + [self _removeStream: queueCArray[i] + withFDSet: &readFDs + otherFDSet: &writeFDs]; + + break; + case QUEUE_REMOVE | QUEUE_WRITE: + [writeStreams removeObjectIdenticalTo: + queueCArray[i]]; + + [self _removeStream: queueCArray[i] + withFDSet: &writeFDs + otherFDSet: &readFDs]; + + break; + default: + assert(0); + } + } + + [queue removeNObjects: count]; + [queueInfo removeNObjects: count]; + } +} + +- (BOOL)observeWithTimeout: (int)timeout +{ + OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init]; + OFStream **cArray; + fd_set readFDs_; + fd_set writeFDs_; + fd_set exceptFDs_; + struct timeval time; + size_t i, count; + + [self _processQueue]; + + if ([self _processCache]) + return YES; + +# ifdef FD_COPY + FD_COPY(&readFDs, &readFDs_); + FD_COPY(&writeFDs, &writeFDs_); + FD_COPY(&exceptFDs, &exceptFDs_); +# else + readFDs_ = readFDs; + writeFDs_ = writeFDs; + exceptFDs_ = exceptFDs; +# endif + + time.tv_sec = timeout / 1000; + time.tv_usec = (timeout % 1000) * 1000; + + if (select(nFDs, &readFDs_, &writeFDs_, &exceptFDs_, + (timeout != -1 ? &time : NULL)) < 1) + return NO; + + if (FD_ISSET(cancelFD[0], &readFDs_)) { + char buffer; +#ifndef _WIN32 + assert(read(cancelFD[0], &buffer, 1) > 0); +#else + assert(recvfrom(cancelFD[0], &buffer, 1, 0, NULL, NULL) > 0); +#endif + } + + cArray = [readStreams cArray]; + count = [readStreams count]; + + for (i = 0; i < count; i++) { + int fileDescriptor = [cArray[i] fileDescriptor]; + + if (FD_ISSET(fileDescriptor, &readFDs_)) { + [delegate streamDidBecomeReadyForReading: cArray[i]]; + [pool releaseObjects]; + } + + if (FD_ISSET(fileDescriptor, &exceptFDs_)) { + [delegate streamDidReceiveException: cArray[i]]; + [pool releaseObjects]; + + /* + * Prevent calling it twice in case the FD is in both + * sets. + */ + FD_CLR(fileDescriptor, &exceptFDs_); + } + } + + cArray = [writeStreams cArray]; + count = [writeStreams count]; + + for (i = 0; i < count; i++) { + int fileDescriptor = [cArray[i] fileDescriptor]; + + if (FD_ISSET(fileDescriptor, &writeFDs_)) { + [delegate streamDidBecomeReadyForWriting: cArray[i]]; + [pool releaseObjects]; + } + + if (FD_ISSET(fileDescriptor, &exceptFDs_)) { + [delegate streamDidReceiveException: cArray[i]]; + [pool releaseObjects]; + } + } + + [pool release]; + + return YES; +} +@end DELETED src/OFStreamPollObserver.h Index: src/OFStreamPollObserver.h ================================================================== --- src/OFStreamPollObserver.h +++ src/OFStreamPollObserver.h @@ -1,26 +0,0 @@ -/* - * Copyright (c) 2008, 2009, 2010, 2011 - * Jonathan Schleifer - * - * All rights reserved. - * - * This file is part of ObjFW. It may be distributed under the terms of the - * Q Public License 1.0, which can be found in the file LICENSE.QPL included in - * the packaging of this file. - * - * Alternatively, it may be distributed under the terms of the GNU General - * Public License, either version 2 or 3, which can be found in the file - * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this - * file. - */ - -#import "OFStreamObserver.h" - -@class OFDataArray; - -@interface OFStreamPollObserver: OFStreamObserver -{ - OFDataArray *FDs; - OFMutableDictionary *FDToStream; -} -@end DELETED src/OFStreamPollObserver.m Index: src/OFStreamPollObserver.m ================================================================== --- src/OFStreamPollObserver.m +++ src/OFStreamPollObserver.m @@ -1,239 +0,0 @@ -/* - * Copyright (c) 2008, 2009, 2010, 2011 - * Jonathan Schleifer - * - * All rights reserved. - * - * This file is part of ObjFW. It may be distributed under the terms of the - * Q Public License 1.0, which can be found in the file LICENSE.QPL included in - * the packaging of this file. - * - * Alternatively, it may be distributed under the terms of the GNU General - * Public License, either version 2 or 3, which can be found in the file - * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this - * file. - */ - -#include "config.h" - -#define __NO_EXT_QNX - -#include -#include -#include - -#import "OFStreamPollObserver.h" -#import "OFStream.h" -#import "OFArray.h" -#import "OFDictionary.h" -#import "OFDataArray.h" -#import "OFNumber.h" -#import "OFAutoreleasePool.h" - -#import "OFOutOfRangeException.h" - -enum { - QUEUE_ADD = 0, - QUEUE_REMOVE = 1, - QUEUE_READ = 0, - QUEUE_WRITE = 2 -}; - -@implementation OFStreamPollObserver - -- init -{ - self = [super init]; - - @try { - struct pollfd p = { 0, POLLIN, 0 }; - - FDs = [[OFDataArray alloc] initWithItemSize: - sizeof(struct pollfd)]; - FDToStream = [[OFMutableDictionary alloc] init]; - - p.fd = cancelFD[0]; - [FDs addItem: &p]; - } @catch (id e) { - [self release]; - @throw e; - } - - return self; -} - -- (void)dealloc -{ - [FDToStream release]; - [FDs release]; - - [super dealloc]; -} - - -- (void)_addStream: (OFStream*)stream - withEvents: (short)events -{ - struct pollfd *FDsCArray = [FDs cArray]; - size_t i, count = [FDs count]; - int fileDescriptor = [stream fileDescriptor]; - BOOL found = NO; - - for (i = 0; i < count; i++) { - if (FDsCArray[i].fd == fileDescriptor) { - FDsCArray[i].events |= events; - found = YES; - } - } - - if (!found) { - OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init]; - struct pollfd p = { fileDescriptor, events | POLLERR, 0 }; - [FDs addItem: &p]; - [FDToStream setObject: stream - forKey: [OFNumber numberWithInt: - fileDescriptor]]; - [pool release]; - } -} - -- (void)_removeStream: (OFStream*)stream - withEvents: (short)events -{ - struct pollfd *FDsCArray = [FDs cArray]; - size_t i, nFDs = [FDs count]; - int fileDescriptor = [stream fileDescriptor]; - - for (i = 0; i < nFDs; i++) { - if (FDsCArray[i].fd == fileDescriptor) { - OFAutoreleasePool *pool; - - FDsCArray[i].events &= ~events; - - if ((FDsCArray[i].events & ~POLLERR) != 0) - return; - - pool = [[OFAutoreleasePool alloc] init]; - - [FDs removeItemAtIndex: i]; - [FDToStream removeObjectForKey: - [OFNumber numberWithInt: fileDescriptor]]; - - [pool release]; - } - } -} - -- (void)_processQueue -{ - @synchronized (queue) { - OFStream **queueCArray = [queue cArray]; - OFNumber **queueInfoCArray = [queueInfo cArray]; - size_t i, count = [queue count]; - - for (i = 0; i < count; i++) { - switch ([queueInfoCArray[i] intValue]) { - case QUEUE_ADD | QUEUE_READ: - [readStreams addObject: queueCArray[i]]; - - [self _addStream: queueCArray[i] - withEvents: POLLIN]; - - break; - case QUEUE_ADD | QUEUE_WRITE: - [writeStreams addObject: queueCArray[i]]; - - [self _addStream: queueCArray[i] - withEvents: POLLOUT]; - - break; - case QUEUE_REMOVE | QUEUE_READ: - [readStreams removeObjectIdenticalTo: - queueCArray[i]]; - - [self _removeStream: queueCArray[i] - withEvents: POLLIN]; - - break; - case QUEUE_REMOVE | QUEUE_WRITE: - [writeStreams removeObjectIdenticalTo: - queueCArray[i]]; - - [self _removeStream: queueCArray[i] - withEvents: POLLOUT]; - - break; - default: - assert(0); - } - } - - [queue removeNObjects: count]; - [queueInfo removeNObjects: count]; - } -} - -- (BOOL)observeWithTimeout: (int)timeout -{ - OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init]; - struct pollfd *FDsCArray; - size_t i, nFDs; - - [self _processQueue]; - - if ([self _processCache]) - return YES; - - FDsCArray = [FDs cArray]; - nFDs = [FDs count]; - -#ifdef OPEN_MAX - if (nFDs > OPEN_MAX) - @throw [OFOutOfRangeException newWithClass: isa]; -#endif - - if (poll(FDsCArray, (nfds_t)nFDs, timeout) < 1) - return NO; - - for (i = 0; i < nFDs; i++) { - OFNumber *num; - OFStream *stream; - - if (FDsCArray[i].revents & POLLIN) { - if (FDsCArray[i].fd == cancelFD[0]) { - char buffer; - - assert(read(cancelFD[0], &buffer, 1) > 0); - FDsCArray[i].revents = 0; - - continue; - } - - num = [OFNumber numberWithInt: FDsCArray[i].fd]; - stream = [FDToStream objectForKey: num]; - [delegate streamDidBecomeReadyForReading: stream]; - [pool releaseObjects]; - } - - if (FDsCArray[i].revents & POLLOUT) { - num = [OFNumber numberWithInt: FDsCArray[i].fd]; - stream = [FDToStream objectForKey: num]; - [delegate streamDidBecomeReadyForReading: stream]; - [pool releaseObjects]; - } - - if (FDsCArray[i].revents & POLLERR) { - num = [OFNumber numberWithInt: FDsCArray[i].fd]; - stream = [FDToStream objectForKey: num]; - [delegate streamDidReceiveException: stream]; - [pool releaseObjects]; - } - - FDsCArray[i].revents = 0; - } - - [pool release]; - - return YES; -} -@end DELETED src/OFStreamSelectObserver.h Index: src/OFStreamSelectObserver.h ================================================================== --- src/OFStreamSelectObserver.h +++ src/OFStreamSelectObserver.h @@ -1,30 +0,0 @@ -/* - * Copyright (c) 2008, 2009, 2010, 2011 - * Jonathan Schleifer - * - * All rights reserved. - * - * This file is part of ObjFW. It may be distributed under the terms of the - * Q Public License 1.0, which can be found in the file LICENSE.QPL included in - * the packaging of this file. - * - * Alternatively, it may be distributed under the terms of the GNU General - * Public License, either version 2 or 3, which can be found in the file - * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this - * file. - */ - -#ifdef OF_HAVE_SYS_SELECT_H -# include -#endif - -#import "OFStreamObserver.h" - -@interface OFStreamSelectObserver: OFStreamObserver -{ - fd_set readFDs; - fd_set writeFDs; - fd_set exceptFDs; - int nFDs; -} -@end DELETED src/OFStreamSelectObserver.m Index: src/OFStreamSelectObserver.m ================================================================== --- src/OFStreamSelectObserver.m +++ src/OFStreamSelectObserver.m @@ -1,219 +0,0 @@ -/* - * Copyright (c) 2008, 2009, 2010, 2011 - * Jonathan Schleifer - * - * All rights reserved. - * - * This file is part of ObjFW. It may be distributed under the terms of the - * Q Public License 1.0, which can be found in the file LICENSE.QPL included in - * the packaging of this file. - * - * Alternatively, it may be distributed under the terms of the GNU General - * Public License, either version 2 or 3, which can be found in the file - * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this - * file. - */ - -#include "config.h" - -#define __NO_EXT_QNX - -#include -#include -#include - -#import "OFStreamSelectObserver.h" -#import "OFStream.h" -#import "OFArray.h" -#import "OFNumber.h" -#import "OFAutoreleasePool.h" - -#ifdef _WIN32 -# define close(sock) closesocket(sock) -#endif - -enum { - QUEUE_ADD = 0, - QUEUE_REMOVE = 1, - QUEUE_READ = 0, - QUEUE_WRITE = 2 -}; - -@implementation OFStreamSelectObserver -- init -{ - self = [super init]; - - FD_ZERO(&readFDs); - FD_ZERO(&writeFDs); - - FD_SET(cancelFD[0], &readFDs); - nFDs = cancelFD[0] + 1; - - return self; -} - -- (void)_addStream: (OFStream*)stream - withFDSet: (fd_set*)FDSet -{ - OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init]; - int fileDescriptor = [stream fileDescriptor]; - - FD_SET(fileDescriptor, FDSet); - FD_SET(fileDescriptor, &exceptFDs); - - if (fileDescriptor >= nFDs) - nFDs = fileDescriptor + 1; - - [pool release]; -} - -- (void)_removeStream: (OFStream*)stream - withFDSet: (fd_set*)FDSet - otherFDSet: (fd_set*)otherFDSet -{ - int fileDescriptor = [stream fileDescriptor]; - - FD_CLR(fileDescriptor, FDSet); - - if (!FD_ISSET(fileDescriptor, otherFDSet)) - FD_CLR(fileDescriptor, &exceptFDs); -} - -- (void)_processQueue -{ - @synchronized (queue) { - OFStream **queueCArray = [queue cArray]; - OFNumber **queueInfoCArray = [queueInfo cArray]; - size_t i, count = [queue count]; - - for (i = 0; i < count; i++) { - switch ([queueInfoCArray[i] intValue]) { - case QUEUE_ADD | QUEUE_READ: - [readStreams addObject: queueCArray[i]]; - - [self _addStream: queueCArray[i] - withFDSet: &readFDs]; - - break; - case QUEUE_ADD | QUEUE_WRITE: - [writeStreams addObject: queueCArray[i]]; - - [self _addStream: queueCArray[i] - withFDSet: &writeFDs]; - - break; - case QUEUE_REMOVE | QUEUE_READ: - [readStreams removeObjectIdenticalTo: - queueCArray[i]]; - - [self _removeStream: queueCArray[i] - withFDSet: &readFDs - otherFDSet: &writeFDs]; - - break; - case QUEUE_REMOVE | QUEUE_WRITE: - [writeStreams removeObjectIdenticalTo: - queueCArray[i]]; - - [self _removeStream: queueCArray[i] - withFDSet: &writeFDs - otherFDSet: &readFDs]; - - break; - default: - assert(0); - } - } - - [queue removeNObjects: count]; - [queueInfo removeNObjects: count]; - } -} - -- (BOOL)observeWithTimeout: (int)timeout -{ - OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init]; - OFStream **cArray; - fd_set readFDs_; - fd_set writeFDs_; - fd_set exceptFDs_; - struct timeval time; - size_t i, count; - - [self _processQueue]; - - if ([self _processCache]) - return YES; - -# ifdef FD_COPY - FD_COPY(&readFDs, &readFDs_); - FD_COPY(&writeFDs, &writeFDs_); - FD_COPY(&exceptFDs, &exceptFDs_); -# else - readFDs_ = readFDs; - writeFDs_ = writeFDs; - exceptFDs_ = exceptFDs; -# endif - - time.tv_sec = timeout / 1000; - time.tv_usec = (timeout % 1000) * 1000; - - if (select(nFDs, &readFDs_, &writeFDs_, &exceptFDs_, - (timeout != -1 ? &time : NULL)) < 1) - return NO; - - if (FD_ISSET(cancelFD[0], &readFDs_)) { - char buffer; -#ifndef _WIN32 - assert(read(cancelFD[0], &buffer, 1) > 0); -#else - assert(recvfrom(cancelFD[0], &buffer, 1, 0, NULL, NULL) > 0); -#endif - } - - cArray = [readStreams cArray]; - count = [readStreams count]; - - for (i = 0; i < count; i++) { - int fileDescriptor = [cArray[i] fileDescriptor]; - - if (FD_ISSET(fileDescriptor, &readFDs_)) { - [delegate streamDidBecomeReadyForReading: cArray[i]]; - [pool releaseObjects]; - } - - if (FD_ISSET(fileDescriptor, &exceptFDs_)) { - [delegate streamDidReceiveException: cArray[i]]; - [pool releaseObjects]; - - /* - * Prevent calling it twice in case the FD is in both - * sets. - */ - FD_CLR(fileDescriptor, &exceptFDs_); - } - } - - cArray = [writeStreams cArray]; - count = [writeStreams count]; - - for (i = 0; i < count; i++) { - int fileDescriptor = [cArray[i] fileDescriptor]; - - if (FD_ISSET(fileDescriptor, &writeFDs_)) { - [delegate streamDidBecomeReadyForWriting: cArray[i]]; - [pool releaseObjects]; - } - - if (FD_ISSET(fileDescriptor, &exceptFDs_)) { - [delegate streamDidReceiveException: cArray[i]]; - [pool releaseObjects]; - } - } - - [pool release]; - - return YES; -} -@end