* Copyright (c) 2014 Apple Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
- *
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
* compliance with the License. Please obtain a copy of the License at
* http://www.opensource.apple.com/apsl/ and read it before using this
* file.
- *
+ *
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
* Please see the License for the specific language governing rights and
* limitations under the License.
- *
+ *
* @APPLE_LICENSE_HEADER_END@
*/
/* CFSocket.c
- Copyright (c) 1999-2013, Apple Inc. All rights reserved.
+ Copyright (c) 1999-2014, Apple Inc. All rights reserved.
Responsibility: Christopher Kane
*/
static CFMutableArrayRef __CFAllSockets = NULL;
CFTypeID CFSocketGetTypeID(void) {
- if (_kCFRuntimeNotATypeID == __kCFSocketTypeID) {
- __kCFSocketTypeID = _CFRuntimeRegisterClass(&__CFSocketClass);
+ static dispatch_once_t initOnce;
+ dispatch_once(&initOnce, ^{
+ __kCFSocketTypeID = _CFRuntimeRegisterClass(&__CFSocketClass); // initOnce covered
__CFAllSockets = CFArrayCreateMutable(kCFAllocatorSystemDefault, 0, &kCFTypeArrayCallBacks);
struct rlimit lim1;
int ret1 = getrlimit(RLIMIT_NOFILE, &lim1);
setrlimit(RLIMIT_NOFILE, &lim2);
// we try, but do not go to extraordinary measures
}
- }
+ });
return __kCFSocketTypeID;
}
(2) an individual CFSocket's lock
(3) __CFActiveSocketsLock
*/
-static CFSpinLock_t __CFAllSocketsLock = CFSpinLockInit; /* controls __CFAllSockets */
+static CFLock_t __CFAllSocketsLock = CFLockInit; /* controls __CFAllSockets */
static CFMutableDictionaryRef __CFAllSockets = NULL;
-static CFSpinLock_t __CFActiveSocketsLock = CFSpinLockInit; /* controls __CFRead/WriteSockets, __CFRead/WriteSocketsFds, __CFSocketManagerThread, and __CFSocketManagerIteration */
+static CFLock_t __CFActiveSocketsLock = CFLockInit; /* controls __CFRead/WriteSockets, __CFRead/WriteSocketsFds, __CFSocketManagerThread, and __CFSocketManagerIteration */
static volatile UInt32 __CFSocketManagerIteration = 0;
static CFMutableArrayRef __CFWriteSockets = NULL;
static CFMutableArrayRef __CFReadSockets = NULL;
unsigned closeSignaled:1; // Have we seen FD_CLOSE? (only used on Win32)
unsigned unused:13;
} _f;
- CFSpinLock_t _lock;
- CFSpinLock_t _writeLock;
+ CFLock_t _lock;
+ CFLock_t _writeLock;
CFSocketNativeHandle _socket; /* immutable */
SInt32 _socketType;
SInt32 _errorCode;
int _bufferedReadError;
CFMutableDataRef _leftoverBytes;
+
+ // <rdar://problem/17849895>
+ // If the timeout is set on the CFSocketRef but we never get select() timeout
+ // because we always have some network events so select never times out (e.g. while having a large download).
+ // We need to notify any waiting buffered read clients if there is data available without relying on select timing out.
+ struct timeval _readBufferTimeoutNotificationTime;
+ Boolean _hitTheTimeout;
};
/* Bit 6 in the base reserved bits is used for write-signalled state (mutable) */
}
CF_INLINE void __CFSocketLock(CFSocketRef s) {
- __CFSpinLock(&(s->_lock));
+ __CFLock(&(s->_lock));
}
CF_INLINE void __CFSocketUnlock(CFSocketRef s) {
- __CFSpinUnlock(&(s->_lock));
+ __CFUnlock(&(s->_lock));
}
CF_INLINE Boolean __CFSocketIsConnectionOriented(CFSocketRef s) {
}
CF_EXPORT void __CFSocketInitializeWinSock(void) {
- __CFSpinLock(&__CFActiveSocketsLock);
+ __CFLock(&__CFActiveSocketsLock);
__CFSocketInitializeWinSock_Guts();
- __CFSpinUnlock(&__CFActiveSocketsLock);
+ __CFUnlock(&__CFActiveSocketsLock);
}
CF_PRIVATE void __CFSocketCleanup(void) {
}
}
+
+#if defined(LOG_CFSOCKET)
+
+static CFStringRef someAddrToString(CFAllocatorRef alloc, int (*fun) (int, struct sockaddr*, socklen_t*), const char* name, CFSocketNativeHandle s)
+{
+ CFStringRef resultString = NULL;
+ union {
+ struct sockaddr sa;
+ struct sockaddr_in sa4b;
+ struct sockaddr_in6 sa6b;
+ UInt8 static_buffer[SOCK_MAXADDRLEN];
+ } u;
+ socklen_t addrlen = sizeof(u.static_buffer);
+
+ uint16_t* pPort = NULL;
+ char buffer[1024];
+
+ if ((*fun) (s, &u.sa, &addrlen) != 0)
+ snprintf(buffer, sizeof(buffer), "error %d resolving %s address for socket %d", errno, name, s);
+ else {
+ void* pAddr = NULL;
+
+ switch (u.sa.sa_family) {
+ case AF_INET:
+ pAddr = &u.sa4b.sin_addr;
+ pPort = &u.sa4b.sin_port;
+ break;
+ case AF_INET6:
+ pAddr = &u.sa6b.sin6_addr;
+ pPort = &u.sa6b.sin6_port;
+ break;
+ }
+
+ if (pAddr == NULL || inet_ntop(u.sa.sa_family, pAddr, buffer, sizeof(buffer)) == NULL)
+ snprintf(buffer, sizeof(buffer), "[error %d converting %s address for socket %d]", pAddr != NULL? errno : EBADF, name, s);
+ }
+ if (pPort) {
+ resultString = CFStringCreateWithFormat(alloc, NULL, CFSTR("%s:%d"), buffer, htons(*pPort));
+ } else {
+ resultString = CFStringCreateWithFormat(alloc, NULL, CFSTR("%s"), buffer);
+ }
+ return resultString;
+}
+
+CFStringRef copyPeerAddress(CFAllocatorRef alloc, CFSocketNativeHandle s)
+{
+ return someAddrToString(alloc, getpeername, "peer", s);
+}
+
+CFStringRef copyLocalAddress(CFAllocatorRef alloc, CFSocketNativeHandle s)
+{
+ return someAddrToString(alloc, getsockname, "local", s);
+}
+
+#endif
+
static void __CFSocketHandleRead(CFSocketRef s, Boolean causedByTimeout)
{
CFDataRef data = NULL, address = NULL;
&& (s->_f.client & kCFSocketDataCallBack) != 0 && (s->_f.disabled & kCFSocketDataCallBack) == 0
&& __CFSocketIsScheduled(s)
) {
- __CFSpinLock(&__CFActiveSocketsLock);
+ __CFLock(&__CFActiveSocketsLock);
/* restore socket to fds */
__CFSocketSetFDForRead(s);
- __CFSpinUnlock(&__CFActiveSocketsLock);
+ __CFUnlock(&__CFActiveSocketsLock);
}
} else if (__CFSocketReadCallBackType(s) == kCFSocketAcceptCallBack) {
uint8_t name[MAX_SOCKADDR_LEN];
if ((s->_f.client & kCFSocketAcceptCallBack) != 0 && (s->_f.disabled & kCFSocketAcceptCallBack) == 0
&& __CFSocketIsScheduled(s)
) {
- __CFSpinLock(&__CFActiveSocketsLock);
+ __CFLock(&__CFActiveSocketsLock);
/* restore socket to fds */
__CFSocketSetFDForRead(s);
- __CFSpinUnlock(&__CFActiveSocketsLock);
+ __CFUnlock(&__CFActiveSocketsLock);
}
} else {
__CFSocketLock(s);
fprintf(stdout, "TIMEOUT - but no bytes, restoring to active set\n");
fflush(stdout);
#endif
+ // Clear the timeout notification time if there is no prefetched data left
+ timerclear(&s->_readBufferTimeoutNotificationTime);
- __CFSpinLock(&__CFActiveSocketsLock);
+ __CFLock(&__CFActiveSocketsLock);
/* restore socket to fds */
__CFSocketSetFDForRead(s);
- __CFSpinUnlock(&__CFActiveSocketsLock);
+ __CFUnlock(&__CFActiveSocketsLock);
__CFSocketUnlock(s);
return;
}
/* if our buffer has room, we go ahead and buffer */
if (ctRemaining > 0) {
base = CFDataGetMutableBytePtr(s->_readBuffer);
-
- do {
- ctRead = read(CFSocketGetNative(s), &base[s->_bytesToBufferPos], ctRemaining);
- } while (ctRead == -1 && errno == EAGAIN);
+
+ struct timeval timeBeforeRead = { 0 };
+ gettimeofday(&timeBeforeRead, NULL);
+
+ struct timeval deadlineTime = { 0 };
+ timeradd(&timeBeforeRead, &s->_readBufferTimeout, &deadlineTime);
+
+ struct timeval timeAfterRead = { 0 };
+
+ while (1) {
+ ctRead = read(CFSocketGetNative(s), &base[s->_bytesToBufferPos], ctRemaining);
+
+ if (ctRead >= 0) {
+ break;
+ }
+
+ if (errno != EAGAIN) {
+ break;
+ }
+
+ gettimeofday(&timeAfterRead, NULL);
+
+ if (timercmp(&timeAfterRead, &deadlineTime, >)) {
+#if defined(LOG_CFSOCKET)
+ CFSocketNativeHandle fd = CFSocketGetNative(s);
+ CFStringRef peerName = copyPeerAddress(kCFAllocatorDefault, fd);
+ CFStringRef localName = copyLocalAddress(kCFAllocatorDefault, fd);
+ CFLog(kCFLogLevelCritical, CFSTR("ERROR: Buffered read of %llu bytes failed for fd %d (socket valid? %d fd valid? %d %@ => %@)"), ctRemaining, fd, __CFSocketIsValid(s), __CFNativeSocketIsValid(fd), localName, peerName);
+ if (peerName)
+ CFRelease(peerName);
+ if (localName)
+ CFRelease(localName);
+#endif
+ break;
+ }
+ }
switch (ctRead) {
case -1:
default:
s->_bytesToBufferPos += ctRead;
if (s->_bytesToBuffer != s->_bytesToBufferPos) {
+
+ // Update the timeout notification time
+ struct timeval timeNow = { 0 };
+ gettimeofday(&timeNow, NULL);
+ timeradd(&timeNow, &s->_readBufferTimeout, &s->_readBufferTimeoutNotificationTime);
#if defined(LOG_CFSOCKET)
fprintf(stdout, "READ %ld - need %ld MORE - GOING BACK FOR MORE\n", ctRead, s->_bytesToBuffer - s->_bytesToBufferPos);
#endif
- __CFSpinLock(&__CFActiveSocketsLock);
+ __CFLock(&__CFActiveSocketsLock);
/* restore socket to fds */
__CFSocketSetFDForRead(s);
- __CFSpinUnlock(&__CFActiveSocketsLock);
+ __CFUnlock(&__CFActiveSocketsLock);
__CFSocketUnlock(s);
return;
} else {
+ // Clear the timeout notification time if the buffer is full
+ timerclear(&s->_readBufferTimeoutNotificationTime);
#if defined(LOG_CFSOCKET)
fprintf(stdout, "DONE READING (read %ld bytes) - GOING TO SIGNAL\n", ctRead);
#endif
/* lock ordering is socket lock, activesocketslock */
/* activesocketslock protects our timeout calculation */
__CFSocketLock(s);
- __CFSpinLock(&__CFActiveSocketsLock);
+ __CFLock(&__CFActiveSocketsLock);
if (s->_bytesToBuffer != length) {
CFIndex ctBuffer = s->_bytesToBufferPos - s->_bytesToBufferReadPos;
__CFReadSocketsTimeoutInvalid = true;
}
- __CFSpinUnlock(&__CFActiveSocketsLock);
+ __CFUnlock(&__CFActiveSocketsLock);
__CFSocketUnlock(s);
}
if (EBADF == selectError) {
CFMutableArrayRef invalidSockets = CFArrayCreateMutable(kCFAllocatorSystemDefault, 0, &kCFTypeArrayCallBacks);
- __CFSpinLock(&__CFActiveSocketsLock);
+ __CFLock(&__CFActiveSocketsLock);
CFIndex cnt = CFArrayGetCount(__CFWriteSockets);
CFIndex idx;
for (idx = 0; idx < cnt; idx++) {
clearInvalidFileDescriptors(__CFWriteSocketsFds);
}
- __CFSpinUnlock(&__CFActiveSocketsLock);
+ __CFUnlock(&__CFActiveSocketsLock);
for (idx = 0; idx < cnt; idx++) {
CFSocketInvalidate(((CFSocketRef)CFArrayGetValueAtIndex(invalidSockets, idx)));
}
}
-#ifdef __GNUC__
-__attribute__ ((noreturn)) // mostly interesting for shutting up a warning
-#endif /* __GNUC__ */
-static void __CFSocketManager(void * arg)
+static void *__CFSocketManager(void * arg)
{
pthread_setname_np("com.apple.CFSocket.private");
if (objc_collectingEnabled()) objc_registerThreadWithCollector();
struct timeval* pTimeout = NULL;
struct timeval timeBeforeSelect;
- for (;;) {
- __CFSpinLock(&__CFActiveSocketsLock);
+ for (;;) {
+ __CFLock(&__CFActiveSocketsLock);
__CFSocketManagerIteration++;
#if defined(LOG_CFSOCKET)
fprintf(stdout, "socket manager iteration %lu looking at read sockets ", (unsigned long)__CFSocketManagerIteration);
gettimeofday(&timeBeforeSelect, NULL);
}
- __CFSpinUnlock(&__CFActiveSocketsLock);
+ __CFUnlock(&__CFActiveSocketsLock);
#if DEPLOYMENT_TARGET_WINDOWS
// On Windows, select checks connection failed sockets via the exceptfds parameter. connection succeeded is checked via writefds. We need both.
fprintf(stdout, "Socket manager received timeout - kicking off expired reads (expired delta %ld, %d)\n", deltaTime.tv_sec, deltaTime.tv_usec);
#endif
- __CFSpinLock(&__CFActiveSocketsLock);
+ __CFLock(&__CFActiveSocketsLock);
tempfds = NULL;
cnt = CFArrayGetCount(__CFReadSockets);
}
}
- __CFSpinUnlock(&__CFActiveSocketsLock);
+ __CFUnlock(&__CFActiveSocketsLock);
/* and below, we dispatch through the normal read dispatch mechanism */
}
fprintf(stdout, "socket manager received %c on wakeup socket\n", buffer[0]);
#endif
}
- __CFSpinLock(&__CFActiveSocketsLock);
+ __CFLock(&__CFActiveSocketsLock);
tempfds = NULL;
cnt = CFArrayGetCount(__CFWriteSockets);
for (idx = 0; idx < cnt; idx++) {
}
tempfds = NULL;
cnt = CFArrayGetCount(__CFReadSockets);
+
+ struct timeval timeNow = { 0 };
+ if (pTimeout) {
+ gettimeofday(&timeNow, NULL);
+ }
+
for (idx = 0; idx < cnt; idx++) {
CFSocketRef s = (CFSocketRef)CFArrayGetValueAtIndex(__CFReadSockets, idx);
CFSocketNativeHandle sock = s->_socket;
// in which case we must be sure not to test a bit in the fdset that is
// outside our mask size.
Boolean sockInBounds = (0 <= sock && sock < maxnrfds);
- if (INVALID_SOCKET != sock && sockInBounds && FD_ISSET(sock, readfds)) {
+
+ // Check if we hit the timeout
+ s->_hitTheTimeout = false;
+ if (pTimeout && sockInBounds && 0 != nrfds && !FD_ISSET(sock, readfds) &&
+ timerisset(&s->_readBufferTimeoutNotificationTime) &&
+ timercmp(&timeNow, &s->_readBufferTimeoutNotificationTime, >))
+ {
+ s->_hitTheTimeout = true;
+ }
+
+ if (INVALID_SOCKET != sock && sockInBounds && (FD_ISSET(sock, readfds) || s->_hitTheTimeout)) {
CFArraySetValueAtIndex(selectedReadSockets, selectedReadSocketsIndex, s);
selectedReadSocketsIndex++;
/* socket is removed from fds here, will be restored in read handling or in perform function */
FD_CLR(sock, tempfds);
}
}
- __CFSpinUnlock(&__CFActiveSocketsLock);
+ __CFUnlock(&__CFActiveSocketsLock);
for (idx = 0; idx < selectedWriteSocketsIndex; idx++) {
CFSocketRef s = (CFSocketRef)CFArrayGetValueAtIndex(selectedWriteSockets, idx);
#if defined(LOG_CFSOCKET)
fprintf(stdout, "socket manager signaling socket %d for read\n", s->_socket);
#endif
- __CFSocketHandleRead(s, nrfds == 0);
+ __CFSocketHandleRead(s, nrfds == 0 || s->_hitTheTimeout);
CFArraySetValueAtIndex(selectedReadSockets, idx, kCFNull);
}
selectedReadSocketsIndex = 0;
}
+ return NULL;
}
static CFStringRef __CFSocketCopyDescription(CFTypeRef cf) {
};
CFTypeID CFSocketGetTypeID(void) {
- if (_kCFRuntimeNotATypeID == __kCFSocketTypeID) {
- __kCFSocketTypeID = _CFRuntimeRegisterClass(&__CFSocketClass);
+ static dispatch_once_t initOnce;
+ dispatch_once(&initOnce, ^{
+ __kCFSocketTypeID = _CFRuntimeRegisterClass(&__CFSocketClass); // initOnce covered
#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI
struct rlimit lim1;
int ret1 = getrlimit(RLIMIT_NOFILE, &lim1);
// we try, but do not go to extraordinary measures
}
#endif
- }
+ });
return __kCFSocketTypeID;
}
+#if DEPLOYMENT_TARGET_WINDOWS
+struct _args {
+ void *func;
+ void *arg;
+ HANDLE handle;
+};
+static unsigned __stdcall __CFWinThreadFunc(void *arg) {
+ struct _args *args = (struct _args*)arg;
+ ((void (*)(void *))args->func)(args->arg);
+ CloseHandle(args->handle);
+ CFAllocatorDeallocate(kCFAllocatorSystemDefault, arg);
+ _endthreadex(0);
+ return 0;
+}
+#endif
+
static CFSocketRef _CFSocketCreateWithNative(CFAllocatorRef allocator, CFSocketNativeHandle sock, CFOptionFlags callBackTypes, CFSocketCallBack callout, const CFSocketContext *context, Boolean useExistingInstance) {
CHECK_FOR_FORK();
CFSocketRef memory;
int typeSize = sizeof(memory->_socketType);
- __CFSpinLock(&__CFActiveSocketsLock);
+ __CFLock(&__CFActiveSocketsLock);
if (NULL == __CFReadSockets) __CFSocketInitializeSockets();
- __CFSpinUnlock(&__CFActiveSocketsLock);
- __CFSpinLock(&__CFAllSocketsLock);
+ __CFUnlock(&__CFActiveSocketsLock);
+ __CFLock(&__CFAllSocketsLock);
if (NULL == __CFAllSockets) {
__CFAllSockets = CFDictionaryCreateMutable(kCFAllocatorSystemDefault, 0, NULL, &kCFTypeDictionaryValueCallBacks);
}
if (INVALID_SOCKET != sock && CFDictionaryGetValueIfPresent(__CFAllSockets, (void *)(uintptr_t)sock, (const void **)&memory)) {
if (useExistingInstance) {
- __CFSpinUnlock(&__CFAllSocketsLock);
+ __CFUnlock(&__CFAllSocketsLock);
CFRetain(memory);
return memory;
} else {
#if defined(LOG_CFSOCKET)
fprintf(stdout, "useExistingInstance is FALSE, removing existing instance %p from __CFAllSockets\n", memory);
#endif
- __CFSpinUnlock(&__CFAllSocketsLock);
+ __CFUnlock(&__CFAllSocketsLock);
CFSocketInvalidate(memory);
- __CFSpinLock(&__CFAllSocketsLock);
+ __CFLock(&__CFAllSocketsLock);
}
}
memory = (CFSocketRef)_CFRuntimeCreateInstance(allocator, CFSocketGetTypeID(), sizeof(struct __CFSocket) - sizeof(CFRuntimeBase), NULL);
if (NULL == memory) {
- __CFSpinUnlock(&__CFAllSocketsLock);
+ __CFUnlock(&__CFAllSocketsLock);
return NULL;
}
__CFSocketSetCallBackTypes(memory, callBackTypes);
memory->_f.connected = FALSE;
memory->_f.writableHint = FALSE;
memory->_f.closeSignaled = FALSE;
- memory->_lock = CFSpinLockInit;
- memory->_writeLock = CFSpinLockInit;
+ memory->_lock = CFLockInit;
+ memory->_writeLock = CFLockInit;
memory->_socket = sock;
if (INVALID_SOCKET == sock || 0 != getsockopt(sock, SOL_SOCKET, SO_TYPE, (char *)&(memory->_socketType), (socklen_t *)&typeSize)) memory->_socketType = 0; // cast for WinSock bad API
memory->_errorCode = 0;
memory->_context.release = 0;
memory->_context.copyDescription = 0;
timerclear(&memory->_readBufferTimeout);
+ timerclear(&memory->_readBufferTimeoutNotificationTime);
+ memory->_hitTheTimeout = false;
memory->_readBuffer = NULL;
memory->_bytesToBuffer = 0;
memory->_bytesToBufferPos = 0;
memory->_leftoverBytes = NULL;
if (INVALID_SOCKET != sock) CFDictionaryAddValue(__CFAllSockets, (void *)(uintptr_t)sock, memory);
- if (NULL == __CFSocketManagerThread) __CFSocketManagerThread = __CFStartSimpleThread(__CFSocketManager, 0);
- __CFSpinUnlock(&__CFAllSocketsLock);
+ if (NULL == __CFSocketManagerThread) {
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI || DEPLOYMENT_TARGET_LINUX || DEPLOYMENT_TARGET_FREEBSD
+ pthread_t tid = 0;
+ pthread_attr_t attr;
+ pthread_attr_init(&attr);
+ pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);
+ pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
+ pthread_attr_set_qos_class_np(&attr, qos_class_main(), 0);
+ pthread_create(&tid, &attr, __CFSocketManager, 0);
+ pthread_attr_destroy(&attr);
+//warning CF: we dont actually know that a pthread_t is the same size as void *
+ __CFSocketManagerThread = (void *)tid;
+#elif DEPLOYMENT_TARGET_WINDOWS
+ unsigned tid;
+ struct _args *args = (struct _args*)CFAllocatorAllocate(kCFAllocatorSystemDefault, sizeof(struct _args), 0);
+ if (__CFOASafe) __CFSetLastAllocationEventName(args, "CFUtilities (thread-args)");
+ HANDLE handle;
+ args->func = __CFSocketManager;
+ args->arg = 0;
+ /* The thread is created suspended, because otherwise there would be a race between the assignment below of the handle field, and it's possible use in the thread func above. */
+ args->handle = (HANDLE)_beginthreadex(NULL, 0, __CFWinThreadFunc, args, CREATE_SUSPENDED, &tid);
+ handle = args->handle;
+ ResumeThread(handle);
+ __CFSocketManagerThread = handle;
+#endif
+ }
+ __CFUnlock(&__CFAllSocketsLock);
if (NULL != context) {
void *contextInfo = context->retain ? (void *)context->retain(context->info) : context->info;
__CFSocketLock(memory);
fprintf(stdout, "invalidating socket %d with flags 0x%x disabled 0x%x connected 0x%x\n", s->_socket, s->_f.client, s->_f.disabled, s->_f.connected);
#endif
CFRetain(s);
- __CFSpinLock(&__CFAllSocketsLock);
+ __CFLock(&__CFAllSocketsLock);
__CFSocketLock(s);
if (__CFSocketIsValid(s)) {
SInt32 idx;
__CFSocketUnsetValid(s);
__CFSocketUnsetWriteSignalled(s);
__CFSocketUnsetReadSignalled(s);
- __CFSpinLock(&__CFActiveSocketsLock);
+ __CFLock(&__CFActiveSocketsLock);
idx = CFArrayGetFirstIndexOfValue(__CFWriteSockets, CFRangeMake(0, CFArrayGetCount(__CFWriteSockets)), s);
if (0 <= idx) {
CFArrayRemoveValueAtIndex(__CFWriteSockets, idx);
__CFSocketClearFDForRead(s);
}
previousSocketManagerIteration = __CFSocketManagerIteration;
- __CFSpinUnlock(&__CFActiveSocketsLock);
+ __CFUnlock(&__CFActiveSocketsLock);
CFDictionaryRemoveValue(__CFAllSockets, (void *)(uintptr_t)(s->_socket));
if ((s->_f.client & kCFSocketCloseOnInvalidate) != 0) closesocket(s->_socket);
s->_socket = INVALID_SOCKET;
} else {
__CFSocketUnlock(s);
}
- __CFSpinUnlock(&__CFAllSocketsLock);
+ __CFUnlock(&__CFAllSocketsLock);
CFRelease(s);
#if defined(LOG_CFSOCKET)
CFLog(5, CFSTR("CFSocketInvalidate(%p) done"), s);
#if defined(LOG_CFSOCKET)
fprintf(stdout, "unscheduling socket %d with flags 0x%x disabled 0x%x connected 0x%x for types 0x%lx\n", s->_socket, s->_f.client, s->_f.disabled, s->_f.connected, callBackTypes);
#endif
- __CFSpinLock(&__CFActiveSocketsLock);
+ __CFLock(&__CFActiveSocketsLock);
if ((readCallBackType == kCFSocketAcceptCallBack) || !__CFSocketIsConnectionOriented(s)) s->_f.connected = TRUE;
if (((callBackTypes & kCFSocketWriteCallBack) != 0) || (((callBackTypes & kCFSocketConnectCallBack) != 0) && !s->_f.connected)) {
if (__CFSocketClearFDForWrite(s)) {
if (readCallBackType != kCFSocketReadCallBack) wakeup = true;
}
}
- __CFSpinUnlock(&__CFActiveSocketsLock);
+ __CFUnlock(&__CFActiveSocketsLock);
}
__CFSocketUnlock(s);
}
// Now turn on the callbacks we've determined that we want on
if (turnOnRead || turnOnWrite || turnOnConnect) {
- __CFSpinLock(&__CFActiveSocketsLock);
+ __CFLock(&__CFActiveSocketsLock);
if (turnOnWrite || turnOnConnect) {
if (force) {
SInt32 idx = CFArrayGetFirstIndexOfValue(__CFWriteSockets, CFRangeMake(0, CFArrayGetCount(__CFWriteSockets)), s);
}
if (__CFSocketSetFDForRead(s)) wakeup = true;
}
- __CFSpinUnlock(&__CFActiveSocketsLock);
+ __CFUnlock(&__CFActiveSocketsLock);
}
}
__CFSocketUnlock(s);
__CFSocketLock(s);
s->_socketSetCount--;
if (0 == s->_socketSetCount) {
- __CFSpinLock(&__CFActiveSocketsLock);
+ __CFLock(&__CFActiveSocketsLock);
idx = CFArrayGetFirstIndexOfValue(__CFWriteSockets, CFRangeMake(0, CFArrayGetCount(__CFWriteSockets)), s);
if (0 <= idx) {
// CFLog(5, CFSTR("__CFSocketCancel: removing %p from __CFWriteSockets list"), s);
CFArrayRemoveValueAtIndex(__CFReadSockets, idx);
__CFSocketClearFDForRead(s);
}
- __CFSpinUnlock(&__CFActiveSocketsLock);
+ __CFUnlock(&__CFActiveSocketsLock);
}
if (NULL != s->_runLoops) {
CFMutableArrayRef runLoopsOrig = s->_runLoops;
CONST_STRING_DECL(kCFSocketRetrieveCommand, "Retrieve")
CONST_STRING_DECL(__kCFSocketRegistryRequestRunLoopMode, "CFSocketRegistryRequest")
-static CFSpinLock_t __CFSocketWriteLock_ = CFSpinLockInit;
+static CFLock_t __CFSocketWriteLock_ = CFLockInit;
//#warning can only send on one socket at a time now
CF_INLINE void __CFSocketWriteLock(CFSocketRef s) {
- __CFSpinLock(& __CFSocketWriteLock_);
+ __CFLock(& __CFSocketWriteLock_);
}
CF_INLINE void __CFSocketWriteUnlock(CFSocketRef s) {
- __CFSpinUnlock(& __CFSocketWriteLock_);
+ __CFUnlock(& __CFSocketWriteLock_);
}
#if NEW_SOCKET
__CFSocketNameRegistryResponse *response = (__CFSocketNameRegistryResponse *)info;
CFDictionaryRef replyDictionary = NULL;
CFPropertyListRef value;
- replyDictionary = (CFDictionaryRef)CFPropertyListCreateFromXMLData(kCFAllocatorSystemDefault, replyData, kCFPropertyListImmutable, NULL);
+ replyDictionary = (CFDictionaryRef)CFPropertyListCreateWithData(kCFAllocatorSystemDefault, replyData, kCFPropertyListImmutable, NULL, NULL);
if (NULL != response->error) *(response->error) = kCFSocketError;
if (NULL != replyDictionary) {
if (CFGetTypeID((CFTypeRef)replyDictionary) == CFDictionaryGetTypeID() && NULL != (value = CFDictionaryGetValue(replyDictionary, kCFSocketResultKey))) {
CFSocketRef s = NULL;
CFRunLoopSourceRef source = NULL;
if (NULL != response->error) *(response->error) = kCFSocketError;
- requestData = CFPropertyListCreateXMLData(kCFAllocatorSystemDefault, requestDictionary);
+ requestData = CFPropertyListCreateData(kCFAllocatorSystemDefault, requestDictionary, kCFPropertyListXMLFormat_v1_0, 0, NULL);
if (NULL != requestData) {
if (NULL != response->error) *(response->error) = kCFSocketTimeout;
s = CFSocketCreateConnectedToSocketSignature(kCFAllocatorSystemDefault, signature, kCFSocketDataCallBack, __CFSocketHandleNameRegistryReply, &context, timeout);