text: /*
   * 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,
   * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
   * 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.
  	Responsibility: Christopher Kane
  */
  
  #define NEW_SOCKET 0
  
  #if NEW_SOCKET
  /*
  
  #include <CoreFoundation/CFSocket.h>
  #include "CFInternal.h"
  #include <dispatch/dispatch.h>
  #include <dispatch/private.h>
  #include <netinet/in.h>
  #include <sys/sysctl.h>
  #include <sys/socket.h>
  #include <sys/ioctl.h>
  #include <sys/stat.h>
  #include <unistd.h>
  #include <dlfcn.h>
  #include <sys/select.h>
  
  
  extern void _CFRunLoopSourceWakeUpRunLoops(CFRunLoopSourceRef rls);
  
  #define INVALID_SOCKET (CFSocketNativeHandle)(-1)
  #define MAX_SOCKADDR_LEN 256
  
  
  DISPATCH_HELPER_FUNCTIONS(sock, CFSocket)
  
  static Boolean sockfd_is_readable(int fd) {
      if (fd < 0 || 1048576 <= fd) HALT;
      size_t sz = ((fd + CHAR_BIT) / CHAR_BIT) + 7; // generous
      fd_set *fdset = malloc(sz);
      int ret;
      do {
          memset(fdset, 0, sz);
          FD_SET(fd, fdset);
          struct timespec ts = {0, 1000UL}; // 1 us
          ret = pselect(fd + 1, fdset, NULL, NULL, &ts, NULL);
      } while (ret < 0 && (EINTR == errno || EAGAIN == errno));
      Boolean isSet = ((0 < ret) && FD_ISSET(fd, fdset));
      free(fdset);
      return isSet;
  }
  
  static Boolean sockfd_is_writeable(int fd) {
      if (fd < 0 || 1048576 <= fd) HALT;
      size_t sz = ((fd + CHAR_BIT) / CHAR_BIT) + 7; // generous
      fd_set *fdset = malloc(sz);
      int ret;
      do {
          memset(fdset, 0, sz);
          FD_SET(fd, fdset);
          struct timespec ts = {0, 1000UL}; // 1 us
          ret = pselect(fd + 1, NULL, fdset, NULL, &ts, NULL);
      } while (ret < 0 && (EINTR == errno || EAGAIN == errno));
      Boolean isSet = ((0 < ret) && FD_ISSET(fd, fdset));
      free(fdset);
      return isSet;
  }
  
  
  enum {
      kCFSocketStateReady = 0,
      kCFSocketStateInvalidating = 1,
      kCFSocketStateInvalid = 2,
      kCFSocketStateDeallocating = 3
  };
  
  struct __shared_blob {
      dispatch_source_t _rdsrc;
      dispatch_source_t _wrsrc;
      CFRunLoopSourceRef _source;
      CFSocketNativeHandle _socket;
      uint8_t _closeFD;
      uint8_t _refCnt;
  };
  
  struct __CFSocket {
      CFRuntimeBase _base;
      struct __shared_blob *_shared; // non-NULL when valid, NULL when invalid
  
      uint8_t _state:2;         // mutable, not written safely
      uint8_t _isSaneFD:1;      // immutable
      uint8_t _connOriented:1;  // immutable
      uint8_t _wantConnect:1;   // immutable
      uint8_t _wantWrite:1;     // immutable
      uint8_t _wantReadType:2;  // immutable
  
      uint8_t _error;
  
      uint8_t _rsuspended:1;
      uint8_t _wsuspended:1;
      uint8_t _readable:1;
      uint8_t _writeable:1;
      uint8_t _unused:4;
  
      uint8_t _reenableRead:1;
      uint8_t _readDisabled:1;
      uint8_t _reenableWrite:1;
      uint8_t _writeDisabled:1;
      uint8_t _connectDisabled:1;
      uint8_t _connected:1;
      uint8_t _leaveErrors:1;
      uint8_t _closeOnInvalidate:1;
  
      int32_t _runLoopCounter;
  
      CFDataRef _address;         // immutable, once created
      CFDataRef _peerAddress;     // immutable, once created
      CFSocketCallBack _callout;  // immutable
      CFSocketContext _context;   // immutable
  };
  
  
  CF_INLINE Boolean __CFSocketIsValid(CFSocketRef sock) {
      return kCFSocketStateReady == sock->_state;
  }
  
  static CFStringRef __CFSocketCopyDescription(CFTypeRef cf) {
      CFSocketRef sock = (CFSocketRef)cf;
      CFStringRef contextDesc = NULL;
      if (NULL != sock->_context.info && NULL != sock->_context.copyDescription) {
          contextDesc = sock->_context.copyDescription(sock->_context.info);
      }
      if (NULL == contextDesc) {
          contextDesc = CFStringCreateWithFormat(kCFAllocatorSystemDefault, NULL, CFSTR("<CFSocket context %p>"), sock->_context.info);
      }
      Dl_info info;
      void *addr = sock->_callout;
      const char *name = (dladdr(addr, &info) && info.dli_saddr == addr && info.dli_sname) ? info.dli_sname : "???";
      int avail = -1;
      ioctlsocket(sock->_shared ? sock->_shared->_socket : -1, FIONREAD, &avail);
      CFStringRef result = CFStringCreateWithFormat(kCFAllocatorSystemDefault, NULL, CFSTR(
              "<CFSocket %p [%p]>{valid = %s, socket = %d, "
              "want connect = %s, connect disabled = %s, "
              "want write = %s, reenable write = %s, write disabled = %s, "
              "want read = %s, reenable read = %s, read disabled = %s, "
              "leave errors = %s, close on invalidate = %s, connected = %s, "
              "last error code = %d, bytes available for read = %d, "
              "source = %p, callout = %s (%p), context = %@}"),
          cf, CFGetAllocator(sock), __CFSocketIsValid(sock) ? "Yes" : "No", sock->_shared ? sock->_shared->_socket : -1,
          sock->_wantConnect ? "Yes" : "No", sock->_connectDisabled ? "Yes" : "No",
          sock->_wantWrite ? "Yes" : "No", sock->_reenableWrite ? "Yes" : "No", sock->_writeDisabled ? "Yes" : "No",
          sock->_wantReadType ? "Yes" : "No", sock->_reenableRead ? "Yes" : "No", sock->_readDisabled? "Yes" : "No",
          sock->_leaveErrors ? "Yes" : "No", sock->_closeOnInvalidate ? "Yes" : "No", sock->_connected ? "Yes" : "No",
          sock->_error, avail,
          sock->_shared ? sock->_shared->_source : NULL, name, addr, contextDesc);
      if (NULL != contextDesc) {
          CFRelease(contextDesc);
      }
      return result;
  }
  
  static void __CFSocketDeallocate(CFTypeRef cf) {
      CHECK_FOR_FORK_RET();
      CFSocketRef sock = (CFSocketRef)cf;
      // Since CFSockets are cached, we can only get here sometime after being invalidated
      sock->_state = kCFSocketStateDeallocating;
      if (sock->_peerAddress) {
          CFRelease(sock->_peerAddress);
          sock->_peerAddress = NULL;
      }
      if (sock->_address) {
          CFRelease(sock->_address);
          sock->_address = NULL;
      }
  }
  
  static CFTypeID __kCFSocketTypeID = _kCFRuntimeNotATypeID;
  
  static const CFRuntimeClass __CFSocketClass = {
      0,
      "CFSocket",
      NULL,      // init
      NULL,      // copy
      __CFSocketDeallocate,
      NULL,      // equal
      NULL,      // hash
      NULL,      // 
      __CFSocketCopyDescription
  };
  
  static CFMutableArrayRef __CFAllSockets = NULL;
  
  CFTypeID CFSocketGetTypeID(void) {
      if (_kCFRuntimeNotATypeID == __kCFSocketTypeID) {
          __kCFSocketTypeID = _CFRuntimeRegisterClass(&__CFSocketClass);
          __CFAllSockets = CFArrayCreateMutable(kCFAllocatorSystemDefault, 0, &kCFTypeArrayCallBacks);
          struct rlimit lim1;
          int ret1 = getrlimit(RLIMIT_NOFILE, &lim1);
          int mib[] = {CTL_KERN, KERN_MAXFILESPERPROC};
          int maxfd = 0;
          size_t len = sizeof(int);
          int ret0 = sysctl(mib, 2, &maxfd, &len, NULL, 0);
          if (0 == ret0 && 0 == ret1 && lim1.rlim_max < maxfd) maxfd = lim1.rlim_max;
          if (0 == ret1 && lim1.rlim_cur < maxfd) {
              struct rlimit lim2 = lim1;
              lim2.rlim_cur += 2304;
              if (maxfd < lim2.rlim_cur) lim2.rlim_cur = maxfd;
              setrlimit(RLIMIT_NOFILE, &lim2);
              // we try, but do not go to extraordinary measures
          }
      }
      return __kCFSocketTypeID;
  }
  
  CFSocketRef CFSocketCreateWithNative(CFAllocatorRef allocator, CFSocketNativeHandle ufd, CFOptionFlags callBackTypes, CFSocketCallBack callout, const CFSocketContext *context) {
      CHECK_FOR_FORK_RET(NULL);
  
      CFSocketGetTypeID(); // cause initialization if necessary
  
      struct stat statbuf;
      int ret = fstat(ufd, &statbuf);
      if (ret < 0) ufd = INVALID_SOCKET;
  
      Boolean sane = false;
      if (INVALID_SOCKET != ufd) {
          uint32_t type = (statbuf.st_mode & S_IFMT);
          sane = (S_IFSOCK == type) || (S_IFIFO == type) || (S_IFCHR == type);
          if (1 && !sane) {
              CFLog(kCFLogLevelWarning, CFSTR("*** CFSocketCreateWithNative(): creating CFSocket with silly fd type (%07o) -- may or may not work"), type);
          }
      }
  
      if (INVALID_SOCKET != ufd) {
          Boolean canHandle = false;
          int tmp_kq = kqueue();
          if (0 <= tmp_kq) {
              struct kevent ev[2];
              EV_SET(&ev[0], ufd, EVFILT_READ, EV_ADD, 0, 0, 0);
              EV_SET(&ev[1], ufd, EVFILT_WRITE, EV_ADD, 0, 0, 0);
              int ret = kevent(tmp_kq, ev, 2, NULL, 0, NULL);
              canHandle = (0 <= ret); // if kevent(ADD) succeeds, can handle
              close(tmp_kq);
          }
          if (1 && !canHandle) {
              CFLog(kCFLogLevelWarning, CFSTR("*** CFSocketCreateWithNative(): creating CFSocket with unsupported fd type -- may or may not work"));
          }
      }
  
      if (INVALID_SOCKET == ufd) {
          // Historically, bad ufd was allowed, but gave an uncached and already-invalid CFSocketRef
          SInt32 size = sizeof(struct __CFSocket) - sizeof(CFRuntimeBase);
          CFSocketRef memory = (CFSocketRef)_CFRuntimeCreateInstance(allocator, CFSocketGetTypeID(), size, NULL);
          if (NULL == memory) {
              return NULL;
          }
          memory->_callout = callout;
          memory->_state = kCFSocketStateInvalid;
          return memory;
      }
  
      __block CFSocketRef sock = NULL;
      dispatch_sync(__sockQueue(), ^{
              for (CFIndex idx = 0, cnt = CFArrayGetCount(__CFAllSockets); idx < cnt; idx++) {
                  CFSocketRef s = (CFSocketRef)CFArrayGetValueAtIndex(__CFAllSockets, idx);
                  if (s->_shared->_socket == ufd) {
                      CFRetain(s);
                      sock = s;
                      return;
                  }
              }
  
              SInt32 size = sizeof(struct __CFSocket) - sizeof(CFRuntimeBase);
              CFSocketRef memory = (CFSocketRef)_CFRuntimeCreateInstance(allocator, CFSocketGetTypeID(), size, NULL);
              if (NULL == memory) {
                  return;
              }
  
              int socketType = 0;
              if (INVALID_SOCKET != ufd) {
                  socklen_t typeSize = sizeof(socketType);
                  int ret = getsockopt(ufd, SOL_SOCKET, SO_TYPE, (void *)&socketType, (socklen_t *)&typeSize);
                  if (ret < 0) socketType = 0;
              }
  
              memory->_rsuspended = true;
              memory->_wsuspended = true;
              memory->_readable = false;
              memory->_writeable = false;
  
              memory->_isSaneFD = sane ? 1 : 0;
              memory->_wantReadType = (callBackTypes & 0x3);
              memory->_reenableRead = memory->_wantReadType ? true : false;
              memory->_readDisabled = false;
              memory->_wantWrite = (callBackTypes & kCFSocketWriteCallBack) ? true : false;
              memory->_reenableWrite = false;
              memory->_writeDisabled = false;
              memory->_wantConnect = (callBackTypes & kCFSocketConnectCallBack) ? true : false;
              memory->_connectDisabled = false;
              memory->_leaveErrors = false;
              memory->_closeOnInvalidate = true;
              memory->_connOriented = (SOCK_STREAM == socketType || SOCK_SEQPACKET == socketType);
              memory->_connected = (memory->_wantReadType == kCFSocketAcceptCallBack || !memory->_connOriented) ? true : false;
  
              memory->_error = 0;
              memory->_runLoopCounter = 0;
              memory->_address = NULL;
              memory->_peerAddress = NULL;
              memory->_context.info = NULL;
              memory->_context.retain = NULL;
              memory->_context.release = NULL;
              memory->_context.copyDescription = NULL;
              memory->_callout = callout;
              if (NULL != context) {
                  objc_memmove_collectable(&memory->_context, context, sizeof(CFSocketContext));
                  memory->_context.info = context->retain ? (void *)context->retain(context->info) : context->info;
              }
  
              struct __shared_blob *shared = malloc(sizeof(struct __shared_blob));
              shared->_rdsrc = NULL;
              shared->_wrsrc = NULL;
              shared->_source = NULL;
              shared->_socket = ufd;
              shared->_closeFD = true; // copy of _closeOnInvalidate
              shared->_refCnt = 1; // one for the CFSocket
              memory->_shared = shared;
  
              if (memory->_wantReadType) {
                  dispatch_source_t dsrc = NULL;
                  if (sane) {
                      dsrc = dispatch_source_create(DISPATCH_SOURCE_TYPE_READ, ufd, 0, __sockQueue());
                  } else {
                      dsrc = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, __sockQueue());
                      dispatch_source_set_timer(dsrc, dispatch_time(DISPATCH_TIME_NOW, 0), NSEC_PER_SEC / 2, NSEC_PER_SEC);
                  }
                  dispatch_block_t event_block = ^{
                          memory->_readable = true;
                          if (!memory->_rsuspended) {
                              dispatch_suspend(dsrc);
  // CFLog(5, CFSTR("suspend %p due to read event block"), memory);
                              memory->_rsuspended = true;
                          }
                          if (shared->_source) {
                              CFRunLoopSourceSignal(shared->_source);
                              _CFRunLoopSourceWakeUpRunLoops(shared->_source);
                          }
                      };
                  dispatch_block_t cancel_block = ^{
                          shared->_rdsrc = NULL;
                          shared->_refCnt--;
                          if (0 == shared->_refCnt) {
                              if (shared->_closeFD) {
                                  // thoroughly stop anything else from using the fd
                                  (void)shutdown(shared->_socket, SHUT_RDWR);
                                  int nullfd = open("/dev/null", O_RDONLY);
                                  dup2(nullfd, shared->_socket);
                                  close(nullfd);
                                  close(shared->_socket);
                              }
                              free(shared);
                          }
                          dispatch_release(dsrc);
                      };
                  dispatch_source_set_event_handler(dsrc, event_block);
                  dispatch_source_set_cancel_handler(dsrc, cancel_block);
                  shared->_rdsrc = dsrc;
              }
              if (memory->_wantWrite || memory->_wantConnect) {
                  dispatch_source_t dsrc = NULL;
                  if (sane) {
                      dsrc = dispatch_source_create(DISPATCH_SOURCE_TYPE_WRITE, ufd, 0, __sockQueue());
                  } else {
                      dsrc = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, __sockQueue());
                      dispatch_source_set_timer(dsrc, dispatch_time(DISPATCH_TIME_NOW, 0), NSEC_PER_SEC / 2, NSEC_PER_SEC);
                  }
                  dispatch_block_t event_block = ^{
                          memory->_writeable = true;
                          if (!memory->_wsuspended) {
                              dispatch_suspend(dsrc);
  // CFLog(5, CFSTR("suspend %p due to write event block"), memory);
                              memory->_wsuspended = true;
                          }
                          if (shared->_source) {
                              CFRunLoopSourceSignal(shared->_source);
                              _CFRunLoopSourceWakeUpRunLoops(shared->_source);
                          }
                      };
                  dispatch_block_t cancel_block = ^{
                          shared->_wrsrc = NULL;
                          shared->_refCnt--;
                          if (0 == shared->_refCnt) {
                              if (shared->_closeFD) {
                                  // thoroughly stop anything else from using the fd
                                  (void)shutdown(shared->_socket, SHUT_RDWR);
                                  int nullfd = open("/dev/null", O_RDONLY);
                                  dup2(nullfd, shared->_socket);
                                  close(nullfd);
                                  close(shared->_socket);
                              }
                              free(shared);
                          }
                          dispatch_release(dsrc);
                      };
                  dispatch_source_set_event_handler(dsrc, event_block);
                  dispatch_source_set_cancel_handler(dsrc, cancel_block);
                  shared->_wrsrc = dsrc;
              }
  
              if (shared->_rdsrc) {
                  shared->_refCnt++;
              }
              if (shared->_wrsrc) {
                  shared->_refCnt++;
              }
  
              memory->_state = kCFSocketStateReady;
              CFArrayAppendValue(__CFAllSockets, memory);
              sock = memory;
          });
  // CFLog(5, CFSTR("CFSocketCreateWithNative(): created socket %p with callbacks 0x%x"), sock, callBackTypes);
      if (sock && !CFSocketIsValid(sock)) { // must do this outside lock to avoid deadlock
          CFRelease(sock);
          sock = NULL;
      }
      return sock;
  }
  
  CFSocketNativeHandle CFSocketGetNative(CFSocketRef sock) {
      CHECK_FOR_FORK_RET(INVALID_SOCKET);
      __CFGenericValidateType(sock, CFSocketGetTypeID());
      return sock->_shared ? sock->_shared->_socket : INVALID_SOCKET;
  }
  
  void CFSocketGetContext(CFSocketRef sock, CFSocketContext *context) {
      __CFGenericValidateType(sock, CFSocketGetTypeID());
      CFAssert1(0 == context->version, __kCFLogAssertion, "%s(): context version not initialized to 0", __PRETTY_FUNCTION__);
      objc_memmove_collectable(context, &sock->_context, sizeof(CFSocketContext));
  }
  
  CFDataRef CFSocketCopyAddress(CFSocketRef sock) {
      CHECK_FOR_FORK_RET(NULL);
      __CFGenericValidateType(sock, CFSocketGetTypeID());
      __block CFDataRef result = NULL;
      dispatch_sync(__sockQueue(), ^{
              if (!sock->_address) {
                  if (!__CFSocketIsValid(sock)) return;
                  uint8_t name[MAX_SOCKADDR_LEN];
                  socklen_t namelen = sizeof(name);
                  int ret = getsockname(sock->_shared->_socket, (struct sockaddr *)name, (socklen_t *)&namelen);
                  if (0 == ret && 0 < namelen) {
                      sock->_address = CFDataCreate(CFGetAllocator(sock), name, namelen);
                  }
              }
              result = sock->_address ? (CFDataRef)CFRetain(sock->_address) : NULL;
          });
      return result;
  }
  
  CFDataRef CFSocketCopyPeerAddress(CFSocketRef sock) {
      CHECK_FOR_FORK_RET(NULL);
      __CFGenericValidateType(sock, CFSocketGetTypeID());
      __block CFDataRef result = NULL;
      dispatch_sync(__sockQueue(), ^{
              if (!sock->_peerAddress) {
                  if (!__CFSocketIsValid(sock)) return;
                  uint8_t name[MAX_SOCKADDR_LEN];
                  socklen_t namelen = sizeof(name);
                  int ret = getpeername(sock->_shared->_socket, (struct sockaddr *)name, (socklen_t *)&namelen);
                  if (0 == ret && 0 < namelen) {
                      sock->_peerAddress = CFDataCreate(CFGetAllocator(sock), name, namelen);
                  }
              }
              result = sock->_peerAddress ? (CFDataRef)CFRetain(sock->_peerAddress) : NULL;
          });
      return result;
  }
  
  CFOptionFlags CFSocketGetSocketFlags(CFSocketRef sock) {
      CHECK_FOR_FORK();
      __CFGenericValidateType(sock, CFSocketGetTypeID());
      __block CFOptionFlags flags = 0;
      dispatch_sync(__sockQueue(), ^{
              if (sock->_reenableRead) flags |= sock->_wantReadType; // flags are same as types here
              if (sock->_reenableWrite) flags |= kCFSocketAutomaticallyReenableWriteCallBack;
              if (sock->_leaveErrors) flags |= kCFSocketLeaveErrors;
              if (sock->_closeOnInvalidate) flags |= kCFSocketCloseOnInvalidate;
          });
      return flags;
  }
  
  void CFSocketSetSocketFlags(CFSocketRef sock, CFOptionFlags flags) {
      CHECK_FOR_FORK();
  // CFLog(5, CFSTR("CFSocketSetSocketFlags(%p, 0x%x) starting"), sock, flags);
      __CFGenericValidateType(sock, CFSocketGetTypeID());
      dispatch_sync(__sockQueue(), ^{
              sock->_reenableRead = (sock->_wantReadType && ((flags & 0x3) == sock->_wantReadType)) ? true : false;
              sock->_reenableWrite = (sock->_wantWrite && (flags & kCFSocketAutomaticallyReenableWriteCallBack)) ? true : false;
              sock->_leaveErrors = (flags & kCFSocketLeaveErrors) ? true : false;
              sock->_closeOnInvalidate = (flags & kCFSocketCloseOnInvalidate) ? true : false;
              if (sock->_shared) sock->_shared->_closeFD = sock->_closeOnInvalidate;
          });
  // CFLog(5, CFSTR("CFSocketSetSocketFlags(%p, 0x%x) done"), sock, flags);
  }
  
  void CFSocketEnableCallBacks(CFSocketRef sock, CFOptionFlags callBackTypes) {
      CHECK_FOR_FORK_RET();
      __CFGenericValidateType(sock, CFSocketGetTypeID());
  // CFLog(5, CFSTR("CFSocketEnableCallBacks(%p, 0x%x) starting"), sock, callBackTypes);
      dispatch_sync(__sockQueue(), ^{
              if (!__CFSocketIsValid(sock)) return;
              if (sock->_wantReadType && (callBackTypes & 0x3) == sock->_wantReadType) {
                  if (sockfd_is_readable(sock->_shared->_socket)) {
                      sock->_readable = true;
  // CFLog(5, CFSTR("CFSocketEnableCallBacks(%p, 0x%x) socket is readable"), sock, callBackTypes);
                      if (!sock->_rsuspended) {
                          dispatch_suspend(sock->_shared->_rdsrc);
                          sock->_rsuspended = true;
                      }
                      // If the source exists, but is now invalid, this next stuff is relatively harmless.
                      if (sock->_shared->_source) {
                          CFRunLoopSourceSignal(sock->_shared->_source);
                          _CFRunLoopSourceWakeUpRunLoops(sock->_shared->_source);
                      }
                  } else if (sock->_rsuspended && sock->_shared->_rdsrc) {
                      sock->_rsuspended = false;
                      dispatch_resume(sock->_shared->_rdsrc);
                  }
                  sock->_readDisabled = false;
              }
              if (sock->_wantWrite && (callBackTypes & kCFSocketWriteCallBack)) {
                  if (sockfd_is_writeable(sock->_shared->_socket)) {
                      sock->_writeable = true;
                      if (!sock->_wsuspended) {
                          dispatch_suspend(sock->_shared->_wrsrc);
                          sock->_wsuspended = true;
                      }
                      // If the source exists, but is now invalid, this next stuff is relatively harmless.
                      if (sock->_shared->_source) {
                          CFRunLoopSourceSignal(sock->_shared->_source);
                          _CFRunLoopSourceWakeUpRunLoops(sock->_shared->_source);
                      }
                  } else if (sock->_wsuspended && sock->_shared->_wrsrc) {
                      sock->_wsuspended = false;
                      dispatch_resume(sock->_shared->_wrsrc);
                  }
                  sock->_writeDisabled = false;
              }
              if (sock->_wantConnect && !sock->_connected && (callBackTypes & kCFSocketConnectCallBack)) {
                  if (sockfd_is_writeable(sock->_shared->_socket)) {
                      sock->_writeable = true;
                      if (!sock->_wsuspended) {
                          dispatch_suspend(sock->_shared->_wrsrc);
                          sock->_wsuspended = true;
                      }
                      // If the source exists, but is now invalid, this next stuff is relatively harmless.
                      if (sock->_shared->_source) {
                          CFRunLoopSourceSignal(sock->_shared->_source);
                          _CFRunLoopSourceWakeUpRunLoops(sock->_shared->_source);
                      }
                  } else if (sock->_wsuspended && sock->_shared->_wrsrc) {
                      sock->_wsuspended = false;
                      dispatch_resume(sock->_shared->_wrsrc);
                  }
                  sock->_connectDisabled = false;
              }
          });
  // CFLog(5, CFSTR("CFSocketEnableCallBacks(%p, 0x%x) done"), sock, callBackTypes);
  }
  
  void CFSocketDisableCallBacks(CFSocketRef sock, CFOptionFlags callBackTypes) {
      CHECK_FOR_FORK_RET();
      __CFGenericValidateType(sock, CFSocketGetTypeID());
  // CFLog(5, CFSTR("CFSocketDisableCallBacks(%p, 0x%x) starting"), sock, callBackTypes);
      dispatch_sync(__sockQueue(), ^{
              if (!__CFSocketIsValid(sock)) return;
              if (sock->_wantReadType && (callBackTypes & 0x3) == sock->_wantReadType) {
                  if (!sock->_rsuspended && sock->_shared->_rdsrc) {
                      dispatch_suspend(sock->_shared->_rdsrc);
                      sock->_rsuspended = true;
                  }
                  sock->_readDisabled = true;
              }
              if (sock->_wantWrite && (callBackTypes & kCFSocketWriteCallBack)) {
                  if (!sock->_wsuspended && sock->_shared->_wrsrc) {
                      dispatch_suspend(sock->_shared->_wrsrc);
                      sock->_wsuspended = true;
                  }
                  sock->_writeDisabled = true;
              }
              if (sock->_wantConnect && !sock->_connected && (callBackTypes & kCFSocketConnectCallBack)) {
                  if (!sock->_wsuspended && sock->_shared->_wrsrc) {
                      dispatch_suspend(sock->_shared->_wrsrc);
                      sock->_wsuspended = true;
                  }
                  sock->_connectDisabled = true;
              }
          });
  // CFLog(5, CFSTR("CFSocketDisableCallBacks(%p, 0x%x) done"), sock, callBackTypes);
  }
  
  void CFSocketInvalidate(CFSocketRef sock) {
      CHECK_FOR_FORK_RET();
      __CFGenericValidateType(sock, CFSocketGetTypeID());
      CFRetain(sock);
  // CFLog(5, CFSTR("CFSocketInvalidate(%p) starting"), sock);
      __block CFRunLoopSourceRef source = NULL;
      __block Boolean wasReady = false;
      dispatch_sync(__sockQueue(), ^{
              wasReady = (sock->_state == kCFSocketStateReady);
              if (wasReady) {
                  sock->_state = kCFSocketStateInvalidating;
                  OSMemoryBarrier();
                  for (CFIndex idx = 0, cnt = CFArrayGetCount(__CFAllSockets); idx < cnt; idx++) {
                      CFSocketRef s = (CFSocketRef)CFArrayGetValueAtIndex(__CFAllSockets, idx);
                      if (s == sock) {
                          CFArrayRemoveValueAtIndex(__CFAllSockets, idx);
                          break;
                      }
                  }
                  if (sock->_shared->_rdsrc) {
                      dispatch_source_cancel(sock->_shared->_rdsrc);
                      if (sock->_rsuspended) {
                          sock->_rsuspended = false;
                          dispatch_resume(sock->_shared->_rdsrc);
                      }
                  }
                  if (sock->_shared->_wrsrc) {
                      dispatch_source_cancel(sock->_shared->_wrsrc);
                      if (sock->_wsuspended) {
                          sock->_wsuspended = false;
                          dispatch_resume(sock->_shared->_wrsrc);
                      }
                  }
                  source = sock->_shared->_source;
                  sock->_shared->_source = NULL;
                  sock->_shared->_refCnt--;
                  if (0 == sock->_shared->_refCnt) {
                      if (sock->_shared->_closeFD) {
                          // thoroughly stop anything else from using the fd
                          (void)shutdown(sock->_shared->_socket, SHUT_RDWR);
                          int nullfd = open("/dev/null", O_RDONLY);
                          dup2(nullfd, sock->_shared->_socket);
                          close(nullfd);
                          close(sock->_shared->_socket);
                      }
                      free(sock->_shared);
                  }
                  sock->_shared = NULL;
              }
          });
      if (wasReady) {
          if (NULL != source) {
              CFRunLoopSourceInvalidate(source);
              CFRelease(source);
          }
          void *info = sock->_context.info;
          sock->_context.info = NULL;
          if (sock->_context.release) {
              sock->_context.release(info);
          }
          sock->_state = kCFSocketStateInvalid;
          OSMemoryBarrier();
      }
  // CFLog(5, CFSTR("CFSocketInvalidate(%p) done%s"), sock, wasReady ? " -- done on this thread" : "");
      CFRelease(sock);
  }
  
  Boolean CFSocketIsValid(CFSocketRef sock) {
      __CFGenericValidateType(sock, CFSocketGetTypeID());
      if (!__CFSocketIsValid(sock)) return false;
      struct stat statbuf;
      int ret = sock->_shared ? fstat(sock->_shared->_socket, &statbuf) : -1;
      if (ret < 0) {
  	CFSocketInvalidate(sock);
  	return false;
      }
      return true;
  }
  
  
  static void __CFSocketPerform(void *info) { // CFRunLoop should only call this on one thread at a time
      CHECK_FOR_FORK_RET();
      CFSocketRef sock = (CFSocketRef)info;
  
  // CFLog(5, CFSTR("__CFSocketPerform(%p) starting '%@'"), sock, sock);
      __block Boolean doRead = false, doWrite = false, doConnect = false, isValid = false;
      __block int fd = INVALID_SOCKET;
      __block SInt32 errorCode = 0;
      __block int new_fd = INVALID_SOCKET;
      __block CFDataRef address = NULL;
      __block CFMutableDataRef data = NULL;
      __block void *context_info = NULL;
      __block void (*context_release)(const void *) = NULL;
      dispatch_sync(__sockQueue(), ^{
              isValid = __CFSocketIsValid(sock);
              if (!isValid) return;
              fd = sock->_shared->_socket;
              doRead = sock->_readable && sock->_wantReadType && !sock->_readDisabled;
              if (doRead) {
                  sock->_readable = false;
                  doRead = sockfd_is_readable(fd);
  // if (!doRead) CFLog(5, CFSTR("__CFSocketPerform(%p) socket is not actually readable"), sock);
              }
              doWrite = sock->_writeable && sock->_wantWrite && !sock->_writeDisabled;
              doConnect = sock->_writeable && sock->_wantConnect && !sock->_connectDisabled && !sock->_connected;
              if (doWrite || doConnect) {
                  sock->_writeable = false;
                  if (doWrite) doWrite = sockfd_is_writeable(fd);
                  if (doConnect) doConnect = sockfd_is_writeable(fd);
              }
              if (!sock->_leaveErrors && (doWrite || doConnect)) { // not on read, for whatever reason
                  int errorSize = sizeof(errorCode);
                  int ret = getsockopt(fd, SOL_SOCKET, SO_ERROR, (void *)&errorCode, (socklen_t *)&errorSize);
                  if (0 != ret) errorCode = 0;
                  sock->_error = errorCode;
              }
              sock->_connected = true;
  // CFLog(5, CFSTR("__CFSocketPerform(%p) doing %d %d %d"), sock, doRead, doWrite, doConnect);
              if (doRead) {
                  switch (sock->_wantReadType) {
                  case kCFSocketReadCallBack:
                      break;
                  case kCFSocketAcceptCallBack: {
                      uint8_t name[MAX_SOCKADDR_LEN];
                      socklen_t namelen = sizeof(name);
                      new_fd = accept(fd, (struct sockaddr *)name, (socklen_t *)&namelen);
                      if (INVALID_SOCKET != new_fd) {
                          address = CFDataCreate(CFGetAllocator(sock), name, namelen);
                      }
                      break;
                  }
                  case kCFSocketDataCallBack: {
                      uint8_t name[MAX_SOCKADDR_LEN];
                      socklen_t namelen = sizeof(name);
                      int avail = 0;
                      int ret = ioctlsocket(fd, FIONREAD, &avail);
                      if (ret < 0 || avail < 256) avail = 256;
                      if ((1 << 20) < avail) avail = (1 << 20);
                      data = CFDataCreateMutable(CFGetAllocator(sock), 0);
                      CFDataSetLength(data, avail);
                      ssize_t len = recvfrom(fd, CFDataGetMutableBytePtr(data), avail, 0, (struct sockaddr *)name, (socklen_t *)&namelen);
                      CFIndex datalen = (len < 0) ? 0 : len;
                      CFDataSetLength(data, datalen);
                      if (0 < namelen) {
                          address = CFDataCreate(CFGetAllocator(sock), name, namelen);
                      } else if (sock->_connOriented) {
                          // cannot call CFSocketCopyPeerAddress(), or deadlock
                          if (!sock->_peerAddress) {
                              uint8_t name[MAX_SOCKADDR_LEN];
                              socklen_t namelen = sizeof(name);
                              int ret = getpeername(sock->_shared->_socket, (struct sockaddr *)name, (socklen_t *)&namelen);
                              if (0 == ret && 0 < namelen) {
                                  sock->_peerAddress = CFDataCreate(CFGetAllocator(sock), name, namelen);
                              }
                          }
                          address = sock->_peerAddress ? (CFDataRef)CFRetain(sock->_peerAddress) : NULL;
                      }
                      if (NULL == address) {
                          address = CFDataCreate(CFGetAllocator(sock), NULL, 0);
                      }
                      break;
                  }
                  }
              }
              if (sock->_reenableRead) {
  // CFLog(5, CFSTR("__CFSocketPerform(%p) reenabling read %d %p"), sock, sock->_rsuspended, sock->_shared->_rdsrc);
                  if (sock->_rsuspended && sock->_shared->_rdsrc) {
                      sock->_rsuspended = false;
                      dispatch_resume(sock->_shared->_rdsrc);
                  }
              }
              if (sock->_reenableWrite) {
                  if (sock->_wsuspended && sock->_shared->_wrsrc) {
                      sock->_wsuspended = false;
                      dispatch_resume(sock->_shared->_wrsrc);
                  }
              }
              if (sock->_context.retain && (doConnect || doRead || doWrite)) {
                  context_info = (void *)sock->_context.retain(sock->_context.info);
                  context_release = sock->_context.release;
              } else {
                  context_info = sock->_context.info;
              }
          });
  // CFLog(5, CFSTR("__CFSocketPerform(%p) isValid:%d, doRead:%d, doWrite:%d, doConnect:%d error:%d"), sock, isValid, doRead, doWrite, doConnect, errorCode);
      if (!isValid || !(doConnect || doRead || doWrite)) return;
  
      Boolean calledOut = false;
      if (doConnect) {
          if (sock->_callout) sock->_callout(sock, kCFSocketConnectCallBack, NULL, (0 != errorCode) ? &errorCode : NULL, context_info);
          calledOut = true;
      }
      if (doRead && (!calledOut || __CFSocketIsValid(sock))) {
          switch (sock->_wantReadType) {
          case kCFSocketReadCallBack:
              if (sock->_callout) sock->_callout(sock, kCFSocketReadCallBack, NULL, NULL, context_info);
              calledOut = true;
              break;
          case kCFSocketAcceptCallBack:
              if (INVALID_SOCKET != new_fd) {
                  if (sock->_callout) sock->_callout(sock, kCFSocketAcceptCallBack, address, &new_fd, context_info);
                  calledOut = true;
              }
              break;
          case kCFSocketDataCallBack:
              if (sock->_callout) sock->_callout(sock, kCFSocketDataCallBack, address, data, context_info);
              calledOut = true;
              break;
          }
      }
      if (doWrite && (!calledOut || __CFSocketIsValid(sock))) {
          if (0 == errorCode) {
              if (sock->_callout) sock->_callout(sock, kCFSocketWriteCallBack, NULL, NULL, context_info);
              calledOut = true;
          }
      }
  
      if (data && 0 == CFDataGetLength(data)) CFSocketInvalidate(sock);
      if (address) CFRelease(address);
      if (data) CFRelease(data);
      if (context_release) {
          context_release(context_info);
      }
  
      CHECK_FOR_FORK_RET();
  // CFLog(5, CFSTR("__CFSocketPerform(%p) done"), sock);
  }
  
  static void __CFSocketSchedule(void *info, CFRunLoopRef rl, CFStringRef mode) {
      CFSocketRef sock = (CFSocketRef)info;
      int32_t newVal = OSAtomicIncrement32Barrier(&sock->_runLoopCounter);
      if (1 == newVal) { // on a transition from 0->1, the old code forced all desired callbacks enabled
          CFOptionFlags types = sock->_wantReadType | (sock->_wantWrite ? kCFSocketWriteCallBack : 0) | (sock->_wantConnect ? kCFSocketConnectCallBack : 0);
          CFSocketEnableCallBacks(sock, types);
      }
      CFRunLoopWakeUp(rl);
  }
  
  static void __CFSocketCancel(void *info, CFRunLoopRef rl, CFStringRef mode) {
      CFSocketRef sock = (CFSocketRef)info;
      OSAtomicDecrement32Barrier(&sock->_runLoopCounter);
      CFRunLoopWakeUp(rl);
  }
  
  CFRunLoopSourceRef CFSocketCreateRunLoopSource(CFAllocatorRef allocator, CFSocketRef sock, CFIndex order) {
      CHECK_FOR_FORK_RET(NULL);
      __CFGenericValidateType(sock, CFSocketGetTypeID());
      if (!CFSocketIsValid(sock)) return NULL;
      __block CFRunLoopSourceRef result = NULL;
      dispatch_sync(__sockQueue(), ^{
              if (!__CFSocketIsValid(sock)) return;
              if (NULL != sock->_shared->_source && !CFRunLoopSourceIsValid(sock->_shared->_source)) {
                  CFRelease(sock->_shared->_source);
                  sock->_shared->_source = NULL;
              }
              if (NULL == sock->_shared->_source) {
                  CFRunLoopSourceContext context;
                  context.version = 0;
                  context.info = (void *)sock;
                  context.retain = (const void *(*)(const void *))CFRetain;
                  context.release = (void (*)(const void *))CFRelease;
                  context.copyDescription = (CFStringRef (*)(const void *))__CFSocketCopyDescription;
                  context.equal = NULL;
                  context.hash = NULL;
                  context.schedule = __CFSocketSchedule;
                  context.cancel = __CFSocketCancel;
                  context.perform = __CFSocketPerform;
                  sock->_shared->_source = CFRunLoopSourceCreate(allocator, order, (CFRunLoopSourceContext *)&context);
                  if (sock->_shared->_source) {
                      if (sock->_wantReadType) {
                          if (sockfd_is_readable(sock->_shared->_socket)) {
                              sock->_readable = true;
                              if (!sock->_rsuspended) {
                                  dispatch_suspend(sock->_shared->_rdsrc);
                                  sock->_rsuspended = true;
                              }
                              if (sock->_shared->_source) {
                                  CFRunLoopSourceSignal(sock->_shared->_source);
                                  _CFRunLoopSourceWakeUpRunLoops(sock->_shared->_source);
                              }
                          } else if (sock->_rsuspended && sock->_shared->_rdsrc) {
                              sock->_rsuspended = false;
                              dispatch_resume(sock->_shared->_rdsrc);
                          }
                      }
                      if (sock->_wantWrite || (sock->_wantConnect && !sock->_connected)) {
                          if (sockfd_is_writeable(sock->_shared->_socket)) {
                              sock->_writeable = true;
                              if (!sock->_wsuspended) {
                                  dispatch_suspend(sock->_shared->_wrsrc);
                                  sock->_wsuspended = true;
                              }
                              if (sock->_shared->_source) {
                                  CFRunLoopSourceSignal(sock->_shared->_source);
                                  _CFRunLoopSourceWakeUpRunLoops(sock->_shared->_source);
                              }
                          } else if (sock->_wsuspended && sock->_shared->_wrsrc) {
                              sock->_wsuspended = false;
                              dispatch_resume(sock->_shared->_wrsrc);
                          }
                      }
                  }
              }
              result = sock->_shared->_source ? (CFRunLoopSourceRef)CFRetain(sock->_shared->_source) : NULL;
          });
  // CFLog(5, CFSTR("CFSocketCreateRunLoopSource(%p) => %p"), sock, result);
      return result;
  }
  
  
  void __CFSocketSetSocketReadBufferAttrs(CFSocketRef s, CFTimeInterval timeout, CFIndex length) {
  }
  
  CFIndex __CFSocketRead(CFSocketRef s, UInt8* buffer, CFIndex length, int* error) {
      *error = 0;
      int ret = read(CFSocketGetNative(s), buffer, length);
      if (ret < 0) {
          *error = errno;
      }
      return ret;
  }
  
  Boolean __CFSocketGetBytesAvailable(CFSocketRef s, CFIndex* ctBytesAvailable) {
      int bytesAvailable;
      int ret = ioctlsocket(CFSocketGetNative(s), FIONREAD, &bytesAvailable);
      if (ret < 0) return false;
      *ctBytesAvailable = (CFIndex)bytesAvailable;
      return true;
  }
  
  */
  #else /* not NEW_SOCKET */
  
  
  #include <CoreFoundation/CFSocket.h>
  #include <sys/types.h>
  #include <math.h>
  #include <limits.h>
  #if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI
  #include <sys/sysctl.h>
  #include <sys/un.h>
  #include <libc.h>
  #include <dlfcn.h>
  #endif
  #include <CoreFoundation/CFArray.h>
  #include <CoreFoundation/CFData.h>
  #include <CoreFoundation/CFDictionary.h>
  #include <CoreFoundation/CFRunLoop.h>
  #include <CoreFoundation/CFString.h>
  #include <CoreFoundation/CFPropertyList.h>
  #include "CFInternal.h"
  
  #if DEPLOYMENT_TARGET_WINDOWS
  
  #define EINPROGRESS WSAEINPROGRESS
  
  // redefine this to the winsock error in this file
  #undef EBADF
  #define EBADF WSAENOTSOCK
  
  #define NBBY 8
  #define NFDBITS	(sizeof(int32_t) * NBBY)
  
  typedef int32_t fd_mask;
  typedef int socklen_t;
  
  #define gettimeofday _NS_gettimeofday
  CF_PRIVATE int _NS_gettimeofday(struct timeval *tv, struct timezone *tz);
  
  // although this is only used for debug info, we define it for compatibility
  #define	timersub(tvp, uvp, vvp) \
      do { \
          (vvp)->tv_sec = (tvp)->tv_sec - (uvp)->tv_sec;		\
          (vvp)->tv_usec = (tvp)->tv_usec - (uvp)->tv_usec;	\
          if ((vvp)->tv_usec < 0) {				\
              (vvp)->tv_sec--;				\
              (vvp)->tv_usec += 1000000;			\
          }							\
      } while (0)
  
  
  #endif // DEPLOYMENT_TARGET_WINDOWS
  
  
  // On Mach we use a v0 RunLoopSource to make client callbacks.  That source is signalled by a
  // separate SocketManager thread who uses select() to watch the sockets' fds.
  
  //#define LOG_CFSOCKET
  
  #if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI
  #define INVALID_SOCKET (CFSocketNativeHandle)(-1)
  #define closesocket(a) close((a))
  #define ioctlsocket(a,b,c) ioctl((a),(b),(c))
  #endif
  
  CF_INLINE int __CFSocketLastError(void) {
  #if DEPLOYMENT_TARGET_WINDOWS
      return WSAGetLastError();
  #else
      return thread_errno();
  #endif
  }
  
  CF_INLINE CFIndex __CFSocketFdGetSize(CFDataRef fdSet) {
      return NBBY * CFDataGetLength(fdSet);
  }
  
  CF_INLINE Boolean __CFSocketFdSet(CFSocketNativeHandle sock, CFMutableDataRef fdSet) {
      /* returns true if a change occurred, false otherwise */
      Boolean retval = false;
      if (INVALID_SOCKET != sock && 0 <= sock) {
          CFIndex numFds = NBBY * CFDataGetLength(fdSet);
          fd_mask *fds_bits;
          if (sock >= numFds) {
              CFIndex oldSize = numFds / NFDBITS, newSize = (sock + NFDBITS) / NFDBITS, changeInBytes = (newSize - oldSize) * sizeof(fd_mask);
              CFDataIncreaseLength(fdSet, changeInBytes);
              fds_bits = (fd_mask *)CFDataGetMutableBytePtr(fdSet);
              memset(fds_bits + oldSize, 0, changeInBytes);
          } else {
              fds_bits = (fd_mask *)CFDataGetMutableBytePtr(fdSet);
          }
          if (!FD_ISSET(sock, (fd_set *)fds_bits)) {
              retval = true;
              FD_SET(sock, (fd_set *)fds_bits);
          }
      }
      return retval;
  }
  
  
  #define MAX_SOCKADDR_LEN 256
  #define MAX_DATA_SIZE 65535
  #define MAX_CONNECTION_ORIENTED_DATA_SIZE 32768
  
  /* locks are to be acquired in the following order:
     (1) __CFAllSocketsLock
     (2) an individual CFSocket's lock
     (3) __CFActiveSocketsLock
  */
  static CFSpinLock_t __CFAllSocketsLock = CFSpinLockInit; /* controls __CFAllSockets */
  static CFMutableDictionaryRef __CFAllSockets = NULL;
  static CFSpinLock_t __CFActiveSocketsLock = CFSpinLockInit; /* controls __CFRead/WriteSockets, __CFRead/WriteSocketsFds, __CFSocketManagerThread, and __CFSocketManagerIteration */
  static volatile UInt32 __CFSocketManagerIteration = 0;
  static CFMutableArrayRef __CFWriteSockets = NULL;
  static CFMutableArrayRef __CFReadSockets = NULL;
  static CFMutableDataRef __CFWriteSocketsFds = NULL;
  static CFMutableDataRef __CFReadSocketsFds = NULL;
  static CFDataRef zeroLengthData = NULL;
  static Boolean __CFReadSocketsTimeoutInvalid = true;  /* rebuild the timeout value before calling select */
  
  static CFSocketNativeHandle __CFWakeupSocketPair[2] = {INVALID_SOCKET, INVALID_SOCKET};
  static void *__CFSocketManagerThread = NULL;
  
  static void __CFSocketDoCallback(CFSocketRef s, CFDataRef data, CFDataRef address, CFSocketNativeHandle sock);
  
  struct __CFSocket {
      CFRuntimeBase _base;
      struct {
          unsigned client:8;	// flags set by client (reenable, CloseOnInvalidate)
          unsigned disabled:8;	// flags marking disabled callbacks
          unsigned connected:1;	// Are we connected yet?  (also true for connectionless sockets)
          unsigned writableHint:1;  // Did the polling the socket show it to be writable?
          unsigned closeSignaled:1;  // Have we seen FD_CLOSE? (only used on Win32)
          unsigned unused:13;
      } _f;
      CFSpinLock_t _lock;
      CFSpinLock_t _writeLock;
      CFSocketNativeHandle _socket;	/* immutable */
      SInt32 _socketType;
      SInt32 _errorCode;
      CFDataRef _address;
      CFDataRef _peerAddress;
      SInt32 _socketSetCount;
      CFRunLoopSourceRef _source0;	// v0 RLS, messaged from SocketMgr
      CFMutableArrayRef _runLoops;
      CFSocketCallBack _callout;		/* immutable */
      CFSocketContext _context;		/* immutable */
      CFMutableArrayRef _dataQueue;	// queues to pass data from SocketMgr thread
      CFMutableArrayRef _addressQueue;
  	
  	struct timeval _readBufferTimeout;
  	CFMutableDataRef _readBuffer;
  	CFIndex _bytesToBuffer;			/* is length of _readBuffer */
  	CFIndex _bytesToBufferPos;		/* where the next _CFSocketRead starts from */
  	CFIndex _bytesToBufferReadPos;	/* Where the buffer will next be read into (always after _bytesToBufferPos, but less than _bytesToBuffer) */
  	Boolean _atEOF;
      int _bufferedReadError;
  	
  	CFMutableDataRef _leftoverBytes;
  };
  
  /* Bit 6 in the base reserved bits is used for write-signalled state (mutable) */
  /* Bit 5 in the base reserved bits is used for read-signalled state (mutable) */
  /* Bit 4 in the base reserved bits is used for invalid state (mutable) */
  /* Bits 0-3 in the base reserved bits are used for callback types (immutable) */
  /* Of this, bits 0-1 are used for the read callback type. */
  
  CF_INLINE Boolean __CFSocketIsWriteSignalled(CFSocketRef s) {
      return (Boolean)__CFBitfieldGetValue(((const CFRuntimeBase *)s)->_cfinfo[CF_INFO_BITS], 6, 6);
  }
  
  CF_INLINE void __CFSocketSetWriteSignalled(CFSocketRef s) {
      __CFBitfieldSetValue(((CFRuntimeBase *)s)->_cfinfo[CF_INFO_BITS], 6, 6, 1);
  }
  
  CF_INLINE void __CFSocketUnsetWriteSignalled(CFSocketRef s) {
      __CFBitfieldSetValue(((CFRuntimeBase *)s)->_cfinfo[CF_INFO_BITS], 6, 6, 0);
  }
  
  CF_INLINE Boolean __CFSocketIsReadSignalled(CFSocketRef s) {
      return (Boolean)__CFBitfieldGetValue(((const CFRuntimeBase *)s)->_cfinfo[CF_INFO_BITS], 5, 5);
  }
  
  CF_INLINE void __CFSocketSetReadSignalled(CFSocketRef s) {
      __CFBitfieldSetValue(((CFRuntimeBase *)s)->_cfinfo[CF_INFO_BITS], 5, 5, 1);
  }
  
  CF_INLINE void __CFSocketUnsetReadSignalled(CFSocketRef s) {
      __CFBitfieldSetValue(((CFRuntimeBase *)s)->_cfinfo[CF_INFO_BITS], 5, 5, 0);
  }
  
  CF_INLINE Boolean __CFSocketIsValid(CFSocketRef s) {
      return (Boolean)__CFBitfieldGetValue(((const CFRuntimeBase *)s)->_cfinfo[CF_INFO_BITS], 4, 4);
  }
  
  CF_INLINE void __CFSocketSetValid(CFSocketRef s) {
      __CFBitfieldSetValue(((CFRuntimeBase *)s)->_cfinfo[CF_INFO_BITS], 4, 4, 1);
  }
  
  CF_INLINE void __CFSocketUnsetValid(CFSocketRef s) {
      __CFBitfieldSetValue(((CFRuntimeBase *)s)->_cfinfo[CF_INFO_BITS], 4, 4, 0);
  }
  
  CF_INLINE uint8_t __CFSocketCallBackTypes(CFSocketRef s) {
      return (uint8_t)__CFBitfieldGetValue(((const CFRuntimeBase *)s)->_cfinfo[CF_INFO_BITS], 3, 0);
  }
  
  CF_INLINE uint8_t __CFSocketReadCallBackType(CFSocketRef s) {
      return (uint8_t)__CFBitfieldGetValue(((const CFRuntimeBase *)s)->_cfinfo[CF_INFO_BITS], 1, 0);
  }
  
  CF_INLINE void __CFSocketSetCallBackTypes(CFSocketRef s, uint8_t types) {
      __CFBitfieldSetValue(((CFRuntimeBase *)s)->_cfinfo[CF_INFO_BITS], 3, 0, types & 0xF);
  }
  
  CF_INLINE void __CFSocketLock(CFSocketRef s) {
      __CFSpinLock(&(s->_lock));
  }
  
  CF_INLINE void __CFSocketUnlock(CFSocketRef s) {
      __CFSpinUnlock(&(s->_lock));
  }
  
  CF_INLINE Boolean __CFSocketIsConnectionOriented(CFSocketRef s) {
      return (SOCK_STREAM == s->_socketType || SOCK_SEQPACKET == s->_socketType);
  }
  
  CF_INLINE Boolean __CFSocketIsScheduled(CFSocketRef s) {
      return (s->_socketSetCount > 0);
  }
  
  CF_INLINE void __CFSocketEstablishAddress(CFSocketRef s) {
      /* socket should already be locked */
      uint8_t name[MAX_SOCKADDR_LEN];
      int namelen = sizeof(name);
      if (__CFSocketIsValid(s) && NULL == s->_address && INVALID_SOCKET != s->_socket && 0 == getsockname(s->_socket, (struct sockaddr *)name, (socklen_t *)&namelen) && NULL != name && 0 < namelen) {
          s->_address = CFDataCreate(CFGetAllocator(s), name, namelen);
      }
  }
  
  CF_INLINE void __CFSocketEstablishPeerAddress(CFSocketRef s) {
      /* socket should already be locked */
      uint8_t name[MAX_SOCKADDR_LEN];
      int namelen = sizeof(name);
      if (__CFSocketIsValid(s) && NULL == s->_peerAddress && INVALID_SOCKET != s->_socket && 0 == getpeername(s->_socket, (struct sockaddr *)name, (socklen_t *)&namelen) && NULL != name && 0 < namelen) {
          s->_peerAddress = CFDataCreate(CFGetAllocator(s), name, namelen);
      }
  }
  
  static Boolean __CFNativeSocketIsValid(CFSocketNativeHandle sock) {
  #if DEPLOYMENT_TARGET_WINDOWS
      SInt32 errorCode = 0;
      int errorSize = sizeof(errorCode);
      return !(0 != getsockopt(sock, SOL_SOCKET, SO_ERROR, (char *)&errorCode, &errorSize) && __CFSocketLastError() == WSAENOTSOCK);
  #else    
      SInt32 flags = fcntl(sock, F_GETFL, 0);
      return !(0 > flags && EBADF == __CFSocketLastError());
  #endif
  }
  
  CF_INLINE Boolean __CFSocketFdClr(CFSocketNativeHandle sock, CFMutableDataRef fdSet) {
      /* returns true if a change occurred, false otherwise */
      Boolean retval = false;
      if (INVALID_SOCKET != sock && 0 <= sock) {
          CFIndex numFds = NBBY * CFDataGetLength(fdSet);
          fd_mask *fds_bits;
          if (sock < numFds) {
              fds_bits = (fd_mask *)CFDataGetMutableBytePtr(fdSet);
              if (FD_ISSET(sock, (fd_set *)fds_bits)) {
                  retval = true;
                  FD_CLR(sock, (fd_set *)fds_bits);
              }
          }
      }
      return retval;
  }
  
  static SInt32 __CFSocketCreateWakeupSocketPair(void) {
  #if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI
      SInt32 error;
  
      error = socketpair(PF_LOCAL, SOCK_DGRAM, 0, __CFWakeupSocketPair);
      if (0 <= error) error = fcntl(__CFWakeupSocketPair[0], F_SETFD, FD_CLOEXEC);
      if (0 <= error) error = fcntl(__CFWakeupSocketPair[1], F_SETFD, FD_CLOEXEC);
      if (0 > error) {
          closesocket(__CFWakeupSocketPair[0]);
          closesocket(__CFWakeupSocketPair[1]);
          __CFWakeupSocketPair[0] = INVALID_SOCKET;
          __CFWakeupSocketPair[1] = INVALID_SOCKET;
      }
  #else
      UInt32 i;
      SInt32 error = 0;
      struct sockaddr_in address[2];
      int namelen = sizeof(struct sockaddr_in);
      for (i = 0; i < 2; i++) {
          __CFWakeupSocketPair[i] = socket(PF_INET, SOCK_DGRAM, 0);
          memset(&(address[i]), 0, sizeof(struct sockaddr_in));
          address[i].sin_family = AF_INET;
          address[i].sin_addr.s_addr = htonl(INADDR_LOOPBACK);
          if (0 <= error) error = bind(__CFWakeupSocketPair[i], (struct sockaddr *)&(address[i]), sizeof(struct sockaddr_in));
          if (0 <= error) error = getsockname(__CFWakeupSocketPair[i], (struct sockaddr *)&(address[i]), &namelen);
          if (sizeof(struct sockaddr_in) != namelen) error = -1;
      }
      if (0 <= error) error = connect(__CFWakeupSocketPair[0], (struct sockaddr *)&(address[1]), sizeof(struct sockaddr_in));
      if (0 <= error) error = connect(__CFWakeupSocketPair[1], (struct sockaddr *)&(address[0]), sizeof(struct sockaddr_in));
      if (0 > error) {
          closesocket(__CFWakeupSocketPair[0]);
          closesocket(__CFWakeupSocketPair[1]);
          __CFWakeupSocketPair[0] = INVALID_SOCKET;
          __CFWakeupSocketPair[1] = INVALID_SOCKET;
      }
  #endif
  #if defined(LOG_CFSOCKET)
      fprintf(stdout, "wakeup socket pair is %d / %d\n", __CFWakeupSocketPair[0], __CFWakeupSocketPair[1]);
  #endif
      return error;
  }
  
  
  // Version 0 RunLoopSources set a mask in an FD set to control what socket activity we hear about.
  // Changes to the master fs_sets occur via these 4 functions.
  CF_INLINE Boolean __CFSocketSetFDForRead(CFSocketRef s) {
      __CFReadSocketsTimeoutInvalid = true;
      Boolean b = __CFSocketFdSet(s->_socket, __CFReadSocketsFds);
      if (b && INVALID_SOCKET != __CFWakeupSocketPair[0]) {
          uint8_t c = 'r';
          send(__CFWakeupSocketPair[0], (const char *)&c, sizeof(c), 0);
      }
      return b;
  }
  
  CF_INLINE Boolean __CFSocketClearFDForRead(CFSocketRef s) {
      __CFReadSocketsTimeoutInvalid = true;
      Boolean b = __CFSocketFdClr(s->_socket, __CFReadSocketsFds);
      if (b && INVALID_SOCKET != __CFWakeupSocketPair[0]) {
          uint8_t c = 's';
          send(__CFWakeupSocketPair[0], (const char *)&c, sizeof(c), 0);
      }
      return b;
  }
  
  CF_INLINE Boolean __CFSocketSetFDForWrite(CFSocketRef s) {
  // CFLog(5, CFSTR("__CFSocketSetFDForWrite(%p)"), s);
      Boolean b = __CFSocketFdSet(s->_socket, __CFWriteSocketsFds);
      if (b && INVALID_SOCKET != __CFWakeupSocketPair[0]) {
          uint8_t c = 'w';
          send(__CFWakeupSocketPair[0], (const char *)&c, sizeof(c), 0);
      }
      return b;
  }
  
  CF_INLINE Boolean __CFSocketClearFDForWrite(CFSocketRef s) {
  // CFLog(5, CFSTR("__CFSocketClearFDForWrite(%p)"), s);
      Boolean b = __CFSocketFdClr(s->_socket, __CFWriteSocketsFds);
      if (b && INVALID_SOCKET != __CFWakeupSocketPair[0]) {
          uint8_t c = 'x';
          send(__CFWakeupSocketPair[0], (const char *)&c, sizeof(c), 0);
      }
      return b;
  }
  
  #if DEPLOYMENT_TARGET_WINDOWS
  static Boolean WinSockUsed = FALSE;
  
  static void __CFSocketInitializeWinSock_Guts(void) {
      if (!WinSockUsed) {
          WinSockUsed = TRUE;
          WORD versionRequested = MAKEWORD(2, 2);
          WSADATA wsaData;
          int errorStatus = WSAStartup(versionRequested, &wsaData);
          if (errorStatus != 0 || LOBYTE(wsaData.wVersion) != LOBYTE(versionRequested) || HIBYTE(wsaData.wVersion) != HIBYTE(versionRequested)) {
              WSACleanup();
              CFLog(kCFLogLevelWarning, CFSTR("*** Could not initialize WinSock subsystem!!!"));
          }
      }
  }
  
  CF_EXPORT void __CFSocketInitializeWinSock(void) {
      __CFSpinLock(&__CFActiveSocketsLock);
      __CFSocketInitializeWinSock_Guts();
      __CFSpinUnlock(&__CFActiveSocketsLock);
  }
  
  CF_PRIVATE void __CFSocketCleanup(void) {
      if (INVALID_SOCKET != __CFWakeupSocketPair[0]) {
          closesocket(__CFWakeupSocketPair[0]);
          __CFWakeupSocketPair[0] = INVALID_SOCKET;
      }
      if (INVALID_SOCKET != __CFWakeupSocketPair[1]) {
          closesocket(__CFWakeupSocketPair[1]);
          __CFWakeupSocketPair[1] = INVALID_SOCKET;
      }
      if (WinSockUsed) {
          // technically this is not supposed to be called here since it will be called from dllmain, but I don't know where else to put it
          WSACleanup();
      }
  }
  
  #endif
  
  // CFNetwork needs to call this, especially for Win32 to get WSAStartup
  static void __CFSocketInitializeSockets(void) {
      __CFWriteSockets = CFArrayCreateMutable(kCFAllocatorSystemDefault, 0, NULL);
      __CFReadSockets = CFArrayCreateMutable(kCFAllocatorSystemDefault, 0, NULL);
      __CFWriteSocketsFds = CFDataCreateMutable(kCFAllocatorSystemDefault, 0);
      __CFReadSocketsFds = CFDataCreateMutable(kCFAllocatorSystemDefault, 0);
      zeroLengthData = CFDataCreateMutable(kCFAllocatorSystemDefault, 0);
  #if DEPLOYMENT_TARGET_WINDOWS
      __CFSocketInitializeWinSock_Guts();
  #endif
      if (0 > __CFSocketCreateWakeupSocketPair()) {
          CFLog(kCFLogLevelWarning, CFSTR("*** Could not create wakeup socket pair for CFSocket!!!"));
      } else {
          UInt32 yes = 1;
          /* wakeup sockets must be non-blocking */
          ioctlsocket(__CFWakeupSocketPair[0], FIONBIO, (u_long *)&yes);
          ioctlsocket(__CFWakeupSocketPair[1], FIONBIO, (u_long *)&yes);
          __CFSocketFdSet(__CFWakeupSocketPair[1], __CFReadSocketsFds);
      }
  }
  
  static CFRunLoopRef __CFSocketCopyRunLoopToWakeUp(CFRunLoopSourceRef src, CFMutableArrayRef runLoops) {
      if (!src) return NULL;
      CFRunLoopRef rl = NULL;
      SInt32 idx, cnt = CFArrayGetCount(runLoops);
      if (0 < cnt) {
          rl = (CFRunLoopRef)CFArrayGetValueAtIndex(runLoops, 0);
          for (idx = 1; NULL != rl && idx < cnt; idx++) {
              CFRunLoopRef value = (CFRunLoopRef)CFArrayGetValueAtIndex(runLoops, idx);
              if (value != rl) rl = NULL;
          }
          if (NULL == rl) {	/* more than one different rl, so we must pick one */
              /* ideally, this would be a run loop which isn't also in a
              * signaled state for this or another source, but that's tricky;
              * we pick one that is running in an appropriate mode for this
              * source, and from those if possible one that is waiting; then
              * we move this run loop to the end of the list to scramble them
              * a bit, and always search from the front */
              Boolean foundIt = false, foundBackup = false;
              SInt32 foundIdx = 0;
              for (idx = 0; !foundIt && idx < cnt; idx++) {
                  CFRunLoopRef value = (CFRunLoopRef)CFArrayGetValueAtIndex(runLoops, idx);
                  CFStringRef currentMode = CFRunLoopCopyCurrentMode(value);
                  if (NULL != currentMode) {
                      if (CFRunLoopContainsSource(value, src, currentMode)) {
                          if (CFRunLoopIsWaiting(value)) {
                              foundIdx = idx;
                              foundIt = true;
                          } else if (!foundBackup) {
                              foundIdx = idx;
                              foundBackup = true;
                          }
                      }
                      CFRelease(currentMode);
                  }
              }
              rl = (CFRunLoopRef)CFArrayGetValueAtIndex(runLoops, foundIdx);
              CFRetain(rl);
              CFArrayRemoveValueAtIndex(runLoops, foundIdx);
              CFArrayAppendValue(runLoops, rl);
          } else {
              CFRetain(rl);
          }
      }
      return rl;
  }
  
  // If callBackNow, we immediately do client callbacks, else we have to signal a v0 RunLoopSource so the
  // callbacks can happen in another thread.
  static void __CFSocketHandleWrite(CFSocketRef s, Boolean callBackNow) {
      SInt32 errorCode = 0;
      int errorSize = sizeof(errorCode);
      CFOptionFlags writeCallBacksAvailable;
      
      if (!CFSocketIsValid(s)) return;
      if (0 != (s->_f.client & kCFSocketLeaveErrors) || 0 != getsockopt(s->_socket, SOL_SOCKET, SO_ERROR, (char *)&errorCode, (socklen_t *)&errorSize)) errorCode = 0;
      // cast for WinSock bad API
  #if defined(LOG_CFSOCKET)
      if (errorCode) fprintf(stdout, "error %ld on socket %d\n", (long)errorCode, s->_socket);
  #endif
      __CFSocketLock(s);
      writeCallBacksAvailable = __CFSocketCallBackTypes(s) & (kCFSocketWriteCallBack | kCFSocketConnectCallBack);
      if ((s->_f.client & kCFSocketConnectCallBack) != 0) writeCallBacksAvailable &= ~kCFSocketConnectCallBack;
      if (!__CFSocketIsValid(s) || ((s->_f.disabled & writeCallBacksAvailable) == writeCallBacksAvailable)) {
          __CFSocketUnlock(s);
          return;
      }
      s->_errorCode = errorCode;
      __CFSocketSetWriteSignalled(s);
  // CFLog(5, CFSTR("__CFSocketHandleWrite() signalling write on socket %p"), s);
  #if defined(LOG_CFSOCKET)
      fprintf(stdout, "write signaling source for socket %d\n", s->_socket);
  #endif
      if (callBackNow) {
          __CFSocketDoCallback(s, NULL, NULL, 0);
      } else {
          CFRunLoopSourceSignal(s->_source0);
          CFMutableArrayRef runLoopsOrig = (CFMutableArrayRef)CFRetain(s->_runLoops);
          CFMutableArrayRef runLoopsCopy = CFArrayCreateMutableCopy(kCFAllocatorSystemDefault, 0, s->_runLoops);
          CFRunLoopSourceRef source0 = s->_source0;
          if (NULL != source0 && !CFRunLoopSourceIsValid(source0)) {
              source0 = NULL;
          }
          if (source0) CFRetain(source0);
          __CFSocketUnlock(s);
          CFRunLoopRef rl = __CFSocketCopyRunLoopToWakeUp(source0, runLoopsCopy);
          if (source0) CFRelease(source0);
          if (NULL != rl) {
              CFRunLoopWakeUp(rl);
              CFRelease(rl);
          }
          __CFSocketLock(s);
          if (runLoopsOrig == s->_runLoops) {
              s->_runLoops = runLoopsCopy;
              runLoopsCopy = NULL;
              CFRelease(runLoopsOrig);
          }
          __CFSocketUnlock(s);
          CFRelease(runLoopsOrig);
          if (runLoopsCopy) CFRelease(runLoopsCopy);
      }
  }
  
  static void __CFSocketHandleRead(CFSocketRef s, Boolean causedByTimeout)
  {
      CFDataRef data = NULL, address = NULL;
      CFSocketNativeHandle sock = INVALID_SOCKET;
      if (!CFSocketIsValid(s)) return;
      if (__CFSocketReadCallBackType(s) == kCFSocketDataCallBack) {
          uint8_t bufferArray[MAX_CONNECTION_ORIENTED_DATA_SIZE], *buffer;
          uint8_t name[MAX_SOCKADDR_LEN];
          int namelen = sizeof(name);
          SInt32 recvlen = 0;
          if (__CFSocketIsConnectionOriented(s)) {
              buffer = bufferArray;
              recvlen = recvfrom(s->_socket, (char *)buffer, MAX_CONNECTION_ORIENTED_DATA_SIZE, 0, (struct sockaddr *)name, (socklen_t *)&namelen);
          } else {
              buffer = (uint8_t *)malloc(MAX_DATA_SIZE);
              if (buffer) recvlen = recvfrom(s->_socket, (char *)buffer, MAX_DATA_SIZE, 0, (struct sockaddr *)name, (socklen_t *)&namelen);
          }
  #if defined(LOG_CFSOCKET)
          fprintf(stdout, "read %ld bytes on socket %d\n", (long)recvlen, s->_socket);
  #endif
          if (0 >= recvlen) {
              //??? should return error if <0
              /* zero-length data is the signal for perform to invalidate */
              data = (CFDataRef)CFRetain(zeroLengthData);
          } else {
              data = CFDataCreate(CFGetAllocator(s), buffer, recvlen);
          }
          if (buffer && buffer != bufferArray) free(buffer);
          __CFSocketLock(s);
          if (!__CFSocketIsValid(s)) {
              CFRelease(data);
              __CFSocketUnlock(s);
              return;
          }
          __CFSocketSetReadSignalled(s);
          if (NULL != name && 0 < namelen) {
              //??? possible optimizations:  uniquing; storing last value
              address = CFDataCreate(CFGetAllocator(s), name, namelen);
          } else if (__CFSocketIsConnectionOriented(s)) {
              if (NULL == s->_peerAddress) __CFSocketEstablishPeerAddress(s);
              if (NULL != s->_peerAddress) address = (CFDataRef)CFRetain(s->_peerAddress);
          }
          if (NULL == address) {
              address = (CFDataRef)CFRetain(zeroLengthData);
          }
          if (NULL == s->_dataQueue) {
              s->_dataQueue = CFArrayCreateMutable(CFGetAllocator(s), 0, &kCFTypeArrayCallBacks);
          }
          if (NULL == s->_addressQueue) {
              s->_addressQueue = CFArrayCreateMutable(CFGetAllocator(s), 0, &kCFTypeArrayCallBacks);
          }
          CFArrayAppendValue(s->_dataQueue, data);
          CFRelease(data);
          CFArrayAppendValue(s->_addressQueue, address);
          CFRelease(address);
          if (0 < recvlen
              && (s->_f.client & kCFSocketDataCallBack) != 0 && (s->_f.disabled & kCFSocketDataCallBack) == 0
              && __CFSocketIsScheduled(s)
          ) {
              __CFSpinLock(&__CFActiveSocketsLock);
              /* restore socket to fds */
              __CFSocketSetFDForRead(s);
              __CFSpinUnlock(&__CFActiveSocketsLock);
          }
      } else if (__CFSocketReadCallBackType(s) == kCFSocketAcceptCallBack) {
          uint8_t name[MAX_SOCKADDR_LEN];
          int namelen = sizeof(name);
          sock = accept(s->_socket, (struct sockaddr *)name, (socklen_t *)&namelen);
          if (INVALID_SOCKET == sock) {
              //??? should return error
              return;
          }
          if (NULL != name && 0 < namelen) {
              address = CFDataCreate(CFGetAllocator(s), name, namelen);
          } else {
              address = (CFDataRef)CFRetain(zeroLengthData);
          }
          __CFSocketLock(s);
          if (!__CFSocketIsValid(s)) {
              closesocket(sock);
              CFRelease(address);
              __CFSocketUnlock(s);
              return;
          }
          __CFSocketSetReadSignalled(s);
          if (NULL == s->_dataQueue) {
              s->_dataQueue = CFArrayCreateMutable(CFGetAllocator(s), 0, NULL);
          }
          if (NULL == s->_addressQueue) {
              s->_addressQueue = CFArrayCreateMutable(CFGetAllocator(s), 0, &kCFTypeArrayCallBacks);
          }
          CFArrayAppendValue(s->_dataQueue, (void *)(uintptr_t)sock);
          CFArrayAppendValue(s->_addressQueue, address);
          CFRelease(address);
          if ((s->_f.client & kCFSocketAcceptCallBack) != 0 && (s->_f.disabled & kCFSocketAcceptCallBack) == 0
              && __CFSocketIsScheduled(s)
          ) {
              __CFSpinLock(&__CFActiveSocketsLock);
              /* restore socket to fds */
              __CFSocketSetFDForRead(s);
              __CFSpinUnlock(&__CFActiveSocketsLock);
          }
      } else {
          __CFSocketLock(s);
          if (!__CFSocketIsValid(s) || (s->_f.disabled & kCFSocketReadCallBack) != 0) {
              __CFSocketUnlock(s);
              return;
          }
  		
  		if (causedByTimeout) {
  #if defined(LOG_CFSOCKET)
  			fprintf(stdout, "TIMEOUT RECEIVED - WILL SIGNAL IMMEDIATELY TO FLUSH (%ld buffered)\n", s->_bytesToBufferPos);
  #endif
                      /* we've got a timeout, but no bytes read, and we don't have any bytes to send.  Ignore the timeout. */
                      if (s->_bytesToBufferPos == 0 && s->_leftoverBytes == NULL) {
  #if defined(LOG_CFSOCKET)
                  fprintf(stdout, "TIMEOUT - but no bytes, restoring to active set\n");
                  fflush(stdout);
  #endif
  
                  __CFSpinLock(&__CFActiveSocketsLock);
                  /* restore socket to fds */
                  __CFSocketSetFDForRead(s);
                  __CFSpinUnlock(&__CFActiveSocketsLock);
                  __CFSocketUnlock(s);
                  return;
              }
  		} else if (s->_bytesToBuffer != 0 && ! s->_atEOF) {
  			UInt8* base;
  			CFIndex ctRead;
  			CFIndex ctRemaining = s->_bytesToBuffer - s->_bytesToBufferPos;
  
  			/* 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);
  
  				switch (ctRead) {
  				case -1:
  					s->_bufferedReadError = errno;
  					s->_atEOF = true;
  #if defined(LOG_CFSOCKET)
  					fprintf(stderr, "BUFFERED READ GOT ERROR %d\n", errno);
  #endif
  					break;
  
  				case 0:
  	#if defined(LOG_CFSOCKET)
  					fprintf(stdout, "DONE READING (EOF) - GOING TO SIGNAL\n");
  	#endif
  					s->_atEOF = true;
  					break;
  			
  				default:
  					s->_bytesToBufferPos += ctRead;
  					if (s->_bytesToBuffer != s->_bytesToBufferPos) {
  	#if defined(LOG_CFSOCKET)
  						fprintf(stdout, "READ %ld - need %ld MORE - GOING BACK FOR MORE\n", ctRead, s->_bytesToBuffer - s->_bytesToBufferPos);
  	#endif
  						__CFSpinLock(&__CFActiveSocketsLock);
  						/* restore socket to fds */
  						__CFSocketSetFDForRead(s);
  						__CFSpinUnlock(&__CFActiveSocketsLock);
  						__CFSocketUnlock(s);
  						return;
  					} else {
  	#if defined(LOG_CFSOCKET)
  						fprintf(stdout, "DONE READING (read %ld bytes) - GOING TO SIGNAL\n", ctRead);
  	#endif
  					}
  				}
  			}
  		}
  
  		__CFSocketSetReadSignalled(s);
      }
  #if defined(LOG_CFSOCKET)
      fprintf(stdout, "read signaling source for socket %d\n", s->_socket);
  #endif
      CFRunLoopSourceSignal(s->_source0);
      CFMutableArrayRef runLoopsOrig = (CFMutableArrayRef)CFRetain(s->_runLoops);
      CFMutableArrayRef runLoopsCopy = CFArrayCreateMutableCopy(kCFAllocatorSystemDefault, 0, s->_runLoops);
      CFRunLoopSourceRef source0 = s->_source0;
      if (NULL != source0 && !CFRunLoopSourceIsValid(source0)) {
          source0 = NULL;
      }
      if (source0) CFRetain(source0);
      __CFSocketUnlock(s);
      CFRunLoopRef rl = __CFSocketCopyRunLoopToWakeUp(source0, runLoopsCopy);
      if (source0) CFRelease(source0);
      if (NULL != rl) {
          CFRunLoopWakeUp(rl);
          CFRelease(rl);
      }
          __CFSocketLock(s);
          if (runLoopsOrig == s->_runLoops) {
              s->_runLoops = runLoopsCopy;
              runLoopsCopy = NULL;
              CFRelease(runLoopsOrig);
          }
          __CFSocketUnlock(s);
          CFRelease(runLoopsOrig);
          if (runLoopsCopy) CFRelease(runLoopsCopy);
  }
  
  static struct timeval* intervalToTimeval(CFTimeInterval timeout, struct timeval* tv)
  {
      if (timeout == 0.0)
          timerclear(tv);
      else {
          tv->tv_sec = (0 >= timeout || INT_MAX <= timeout) ? INT_MAX : (int)(float)floor(timeout);
          tv->tv_usec = (int)((timeout - floor(timeout)) * 1.0E6);
      }
      return tv;
  }
  
  /* note that this returns a pointer to the min value, which won't have changed during
   the dictionary apply, since we've got the active sockets lock held */
  static void _calcMinTimeout_locked(const void* val, void* ctxt)
  {
      CFSocketRef s = (CFSocketRef) val;
      struct timeval** minTime = (struct timeval**) ctxt;
      if (timerisset(&s->_readBufferTimeout) && (*minTime == NULL || timercmp(&s->_readBufferTimeout, *minTime, <)))
          *minTime = &s->_readBufferTimeout;
      else if (s->_leftoverBytes) {
          /* If there's anyone with leftover bytes, they'll need to be awoken immediately */
          static struct timeval sKickerTime = { 0, 0 };
          *minTime = &sKickerTime;
      }
  }
  
  void __CFSocketSetSocketReadBufferAttrs(CFSocketRef s, CFTimeInterval timeout, CFIndex length)
  {
      struct timeval timeoutVal;
      
      intervalToTimeval(timeout, &timeoutVal);
      
      /* lock ordering is socket lock, activesocketslock */
      /* activesocketslock protects our timeout calculation */
      __CFSocketLock(s);
      __CFSpinLock(&__CFActiveSocketsLock);
  
      if (s->_bytesToBuffer != length) {
          CFIndex ctBuffer = s->_bytesToBufferPos - s->_bytesToBufferReadPos;
          
          if (ctBuffer) {
              /* As originally envisaged, you were supposed to be sure to drain the buffer before 
               * issuing another request on the socket.  In practice, there seem to be times when we want to re-use 
               * the stream (or perhaps, are on our way to closing it out) and this policy doesn't work so well.  
               * So, if someone changes the buffer size while we have bytes already buffered, we put them 
               * aside and use them to satisfy any subsequent reads. 
               */
  #if defined(LOG_CFSOCKET)
              fprintf(stdout, "%s(%d): WARNING: shouldn't set read buffer length while data (%ld bytes) is still in the read buffer (leftover total %ld)", __FUNCTION__, __LINE__, ctBuffer, s->_leftoverBytes? CFDataGetLength(s->_leftoverBytes) : 0);
  #endif
              
              if (s->_leftoverBytes == NULL)
                  s->_leftoverBytes = CFDataCreateMutable(CFGetAllocator(s), 0);
              
              /* append the current buffered bytes over.  We'll keep draining _leftoverBytes while we have them... */
              CFDataAppendBytes(s->_leftoverBytes, CFDataGetBytePtr(s->_readBuffer) + s->_bytesToBufferReadPos, ctBuffer);
              CFRelease(s->_readBuffer);
              s->_readBuffer = NULL;
              
              s->_bytesToBuffer = 0;
              s->_bytesToBufferPos = 0;
              s->_bytesToBufferReadPos = 0;
          }
          if (length == 0) {
              s->_bytesToBuffer = 0;
              s->_bytesToBufferPos = 0;
              s->_bytesToBufferReadPos = 0;
              if (s->_readBuffer) {
                  CFRelease(s->_readBuffer);
                  s->_readBuffer = NULL;
              }
              // Zero length buffer, smash the timeout
              timeoutVal.tv_sec = 0;
              timeoutVal.tv_usec = 0;
          } else {
              /* if the buffer shrank, we can re-use the old one */
              if (length > s->_bytesToBuffer) {
                  if (s->_readBuffer) {
                      CFRelease(s->_readBuffer);
                      s->_readBuffer = NULL;
                  }
              }
              
              s->_bytesToBuffer = length;
              s->_bytesToBufferPos = 0;
              s->_bytesToBufferReadPos = 0;
              if (s->_readBuffer == NULL) {
                  s->_readBuffer = CFDataCreateMutable(kCFAllocatorSystemDefault, length);
                  CFDataSetLength(s->_readBuffer, length);
              }
          }
      }
      
      if (timercmp(&s->_readBufferTimeout, &timeoutVal, !=)) {
          s->_readBufferTimeout = timeoutVal;
          __CFReadSocketsTimeoutInvalid = true;
      }
      
      __CFSpinUnlock(&__CFActiveSocketsLock);
      __CFSocketUnlock(s);
  }
  
  CFIndex __CFSocketRead(CFSocketRef s, UInt8* buffer, CFIndex length, int* error)
  {
  #if defined(LOG_CFSOCKET)
  	fprintf(stdout, "READING BYTES FOR SOCKET %d (%ld buffered, out of %ld desired, eof = %d, err = %d)\n", s->_socket, s->_bytesToBufferPos, s->_bytesToBuffer, s->_atEOF, s->_bufferedReadError);
  #endif
  
      CFIndex result = -1;
  
      __CFSocketLock(s);
  
  	*error = 0;
  	
  	/* Any leftover buffered bytes? */
  	if (s->_leftoverBytes) {
  		CFIndex ctBuffer = CFDataGetLength(s->_leftoverBytes);
  #if defined(DEBUG)
  		fprintf(stderr, "%s(%ld): WARNING: Draining %ld leftover bytes first\n\n", __FUNCTION__, (long)__LINE__, (long)ctBuffer);
  #endif
  		if (ctBuffer > length)
  			ctBuffer = length;
  		memcpy(buffer, CFDataGetBytePtr(s->_leftoverBytes), ctBuffer);
  		if (ctBuffer < CFDataGetLength(s->_leftoverBytes))
  			CFDataReplaceBytes(s->_leftoverBytes, CFRangeMake(0, ctBuffer), NULL, 0);
  		else {
  			CFRelease(s->_leftoverBytes);
  			s->_leftoverBytes = NULL;
  		}
  		result = ctBuffer;
  		goto unlock;
  	}
  	
  	/* return whatever we've buffered */
  	if (s->_bytesToBuffer != 0) {
  		CFIndex ctBuffer = s->_bytesToBufferPos - s->_bytesToBufferReadPos;
  		if (ctBuffer > 0) {
  			/* drain our buffer first */
  			if (ctBuffer > length)
  				ctBuffer = length;
  			memcpy(buffer, CFDataGetBytePtr(s->_readBuffer) + s->_bytesToBufferReadPos, ctBuffer);
  			s->_bytesToBufferReadPos += ctBuffer;
  			if (s->_bytesToBufferReadPos == s->_bytesToBufferPos) {
  #if defined(LOG_CFSOCKET)
  				fprintf(stdout, "DRAINED BUFFER - SHOULD START BUFFERING AGAIN!\n");
  #endif
  				s->_bytesToBufferPos = 0;
  				s->_bytesToBufferReadPos = 0;
  			}
  			
  #if defined(LOG_CFSOCKET)
  			fprintf(stdout, "SLURPED %ld BYTES FROM BUFFER %ld LEFT TO READ!\n", ctBuffer, length);
  #endif
  
  			result = ctBuffer;
              goto unlock;
  		}
  	}
  	/* nothing buffered, or no buffer selected */
  	
  	/* Did we get an error on a previous read (or buffered read)? */
  	if (s->_bufferedReadError != 0) {
  #if defined(LOG_CFSOCKET)
  		fprintf(stdout, "RETURNING ERROR %d\n", s->_bufferedReadError);
  #endif
  		*error = s->_bufferedReadError;
          result = -1;
          goto unlock;
  	}
  	
  	/* nothing buffered, if we've hit eof, don't bother reading any more */
  	if (s->_atEOF) {
  #if defined(LOG_CFSOCKET)
  		fprintf(stdout, "RETURNING EOF\n");
  #endif
  		result = 0;
          goto unlock;
  	}
  	
  	/* normal read */
  	result = read(CFSocketGetNative(s), buffer, length);
  #if defined(LOG_CFSOCKET)
  	fprintf(stdout, "READ %ld bytes", result);
  #endif
  
      if (result == 0) {
          /* note that we hit EOF */
          s->_atEOF = true;
      } else if (result < 0) {
          *error = errno;
  
          /* if it wasn't EAGAIN, record it (although we shouldn't get called again) */
          if (*error != EAGAIN) {
              s->_bufferedReadError = *error;
          }
      }
  
  unlock:
      __CFSocketUnlock(s);
  
      return result;
  }
  
  Boolean __CFSocketGetBytesAvailable(CFSocketRef s, CFIndex* ctBytesAvailable)
  {
  	CFIndex ctBuffer = s->_bytesToBufferPos - s->_bytesToBufferReadPos;
  	if (ctBuffer != 0) {
  		*ctBytesAvailable = ctBuffer;
  		return true;
  	} else {
  		int result;
  	    unsigned long bytesAvailable;
  	    result = ioctlsocket(CFSocketGetNative(s), FIONREAD, &bytesAvailable);
  		if (result < 0)
  			return false;
  		*ctBytesAvailable = (CFIndex) bytesAvailable;
  		return true;
  	}
  }
  
  #if defined(LOG_CFSOCKET)
  static void __CFSocketWriteSocketList(CFArrayRef sockets, CFDataRef fdSet, Boolean onlyIfSet) {
      fd_set *tempfds = (fd_set *)CFDataGetBytePtr(fdSet);
      SInt32 idx, cnt;
      for (idx = 0, cnt = CFArrayGetCount(sockets); idx < cnt; idx++) {
          CFSocketRef s = (CFSocketRef)CFArrayGetValueAtIndex(sockets, idx);
          if (FD_ISSET(s->_socket, tempfds)) {
              fprintf(stdout, "%d ", s->_socket);
          } else if (!onlyIfSet) {
              fprintf(stdout, "(%d) ", s->_socket);
          }
      }
  }
  #endif
  
  static void
  clearInvalidFileDescriptors(CFMutableDataRef d)
  {
      if (d) {
          SInt32 count = __CFSocketFdGetSize(d);
          fd_set* s = (fd_set*) CFDataGetMutableBytePtr(d);
          for (SInt32 idx = 0;  idx < count;  idx++) {
              if (FD_ISSET(idx, s))
                  if (! __CFNativeSocketIsValid(idx)) {
                      FD_CLR(idx, s);
                  }
          }
      }
  }
  
  static void
  manageSelectError()
  {
      SInt32 selectError = __CFSocketLastError();
  #if defined(LOG_CFSOCKET)
      fprintf(stdout, "socket manager received error %ld from select\n", (long)selectError);
  #endif
      if (EBADF == selectError) {
          CFMutableArrayRef invalidSockets = CFArrayCreateMutable(kCFAllocatorSystemDefault, 0, &kCFTypeArrayCallBacks);
  
          __CFSpinLock(&__CFActiveSocketsLock);
          CFIndex cnt = CFArrayGetCount(__CFWriteSockets);
          CFIndex idx;
          for (idx = 0; idx < cnt; idx++) {
              CFSocketRef s = (CFSocketRef)CFArrayGetValueAtIndex(__CFWriteSockets, idx);
              if (!__CFNativeSocketIsValid(s->_socket)) {
  #if defined(LOG_CFSOCKET)
                  fprintf(stdout, "socket manager found write socket %d invalid\n", s->_socket);
  #endif
                  CFArrayAppendValue(invalidSockets, s);
              }
          }
          cnt = CFArrayGetCount(__CFReadSockets);
          for (idx = 0; idx < cnt; idx++) {
              CFSocketRef s = (CFSocketRef)CFArrayGetValueAtIndex(__CFReadSockets, idx);
              if (!__CFNativeSocketIsValid(s->_socket)) {
  #if defined(LOG_CFSOCKET)
                  fprintf(stdout, "socket manager found read socket %d invalid\n", s->_socket);
  #endif
                  CFArrayAppendValue(invalidSockets, s);
              }
          }
  
  
          cnt = CFArrayGetCount(invalidSockets);
  
          /* Note that we're doing this only when we got EBADF but otherwise
           * don't have an explicit bad descriptor.  Note that the lock is held now.
           * Finally, note that cnt == 0 doesn't necessarily mean
           * that this loop will do anything, since fd's may have been invalidated
           * while we were in select.
           */
          if (cnt == 0) {
  #if defined(LOG_CFSOCKET)
              fprintf(stdout, "socket manager received EBADF(1): No sockets were marked as invalid, cleaning out fdsets\n");
  #endif
  
              clearInvalidFileDescriptors(__CFReadSocketsFds);
              clearInvalidFileDescriptors(__CFWriteSocketsFds);
          }
  
          __CFSpinUnlock(&__CFActiveSocketsLock);
  
          for (idx = 0; idx < cnt; idx++) {
              CFSocketInvalidate(((CFSocketRef)CFArrayGetValueAtIndex(invalidSockets, idx)));
          }
          CFRelease(invalidSockets);
      }
  }
  
  #ifdef __GNUC__
  __attribute__ ((noreturn))	// mostly interesting for shutting up a warning
  #endif /* __GNUC__ */
  static void __CFSocketManager(void * arg)
  {
      pthread_setname_np("com.apple.CFSocket.private");
      if (objc_collectingEnabled()) objc_registerThreadWithCollector();
      SInt32 nrfds, maxnrfds, fdentries = 1;
      SInt32 rfds, wfds;
      fd_set *exceptfds = NULL;
      fd_set *writefds = (fd_set *)CFAllocatorAllocate(kCFAllocatorSystemDefault, fdentries * sizeof(fd_mask), 0);
      fd_set *readfds = (fd_set *)CFAllocatorAllocate(kCFAllocatorSystemDefault, fdentries * sizeof(fd_mask), 0);
      fd_set *tempfds;
      SInt32 idx, cnt;
      uint8_t buffer[256];
      CFMutableArrayRef selectedWriteSockets = CFArrayCreateMutable(kCFAllocatorSystemDefault, 0, &kCFTypeArrayCallBacks);
      CFMutableArrayRef selectedReadSockets = CFArrayCreateMutable(kCFAllocatorSystemDefault, 0, &kCFTypeArrayCallBacks);
      CFIndex selectedWriteSocketsIndex = 0, selectedReadSocketsIndex = 0;
      
      struct timeval tv;
      struct timeval* pTimeout = NULL;
      struct timeval timeBeforeSelect;
      
      for (;;) {       
          __CFSpinLock(&__CFActiveSocketsLock);
          __CFSocketManagerIteration++;
  #if defined(LOG_CFSOCKET)
          fprintf(stdout, "socket manager iteration %lu looking at read sockets ", (unsigned long)__CFSocketManagerIteration);
          __CFSocketWriteSocketList(__CFReadSockets, __CFReadSocketsFds, FALSE);
          if (0 < CFArrayGetCount(__CFWriteSockets)) {
              fprintf(stdout, " and write sockets ");
              __CFSocketWriteSocketList(__CFWriteSockets, __CFWriteSocketsFds, FALSE);
          }
          fprintf(stdout, "\n");
  #endif
          rfds = __CFSocketFdGetSize(__CFReadSocketsFds);
          wfds = __CFSocketFdGetSize(__CFWriteSocketsFds);
          maxnrfds = __CFMax(rfds, wfds);
          if (maxnrfds > fdentries * (int)NFDBITS) {
              fdentries = (maxnrfds + NFDBITS - 1) / NFDBITS;
              writefds = (fd_set *)CFAllocatorReallocate(kCFAllocatorSystemDefault, writefds, fdentries * sizeof(fd_mask), 0);
              readfds = (fd_set *)CFAllocatorReallocate(kCFAllocatorSystemDefault, readfds, fdentries * sizeof(fd_mask), 0);
          }
          memset(writefds, 0, fdentries * sizeof(fd_mask)); 
          memset(readfds, 0, fdentries * sizeof(fd_mask));
          CFDataGetBytes(__CFWriteSocketsFds, CFRangeMake(0, CFDataGetLength(__CFWriteSocketsFds)), (UInt8 *)writefds);
          CFDataGetBytes(__CFReadSocketsFds, CFRangeMake(0, CFDataGetLength(__CFReadSocketsFds)), (UInt8 *)readfds); 
  		
          if (__CFReadSocketsTimeoutInvalid) {
              struct timeval* minTimeout = NULL;
              __CFReadSocketsTimeoutInvalid = false;
  #if defined(LOG_CFSOCKET)
              fprintf(stdout, "Figuring out which sockets have timeouts...\n");
  #endif
              CFArrayApplyFunction(__CFReadSockets, CFRangeMake(0, CFArrayGetCount(__CFReadSockets)), _calcMinTimeout_locked, (void*) &minTimeout);
  
              if (minTimeout == NULL) {
  #if defined(LOG_CFSOCKET)
                  fprintf(stdout, "No one wants a timeout!\n");
  #endif
                  pTimeout = NULL;
              } else {
  #if defined(LOG_CFSOCKET)
                  fprintf(stdout, "timeout will be %ld, %d!\n", minTimeout->tv_sec, minTimeout->tv_usec);
  #endif
                  tv = *minTimeout;
                  pTimeout = &tv;
              }
          }
  
          if (pTimeout) {
  #if defined(LOG_CFSOCKET)
              fprintf(stdout, "select will have a %ld, %d timeout\n", pTimeout->tv_sec, pTimeout->tv_usec);
  #endif
              gettimeofday(&timeBeforeSelect, NULL);
          }
  		
  		__CFSpinUnlock(&__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.
          exceptfds = writefds;
  #endif
          nrfds = select(maxnrfds, readfds, writefds, exceptfds, pTimeout);
  
  #if defined(LOG_CFSOCKET)
          fprintf(stdout, "socket manager woke from select, ret=%ld\n", (long)nrfds);
  #endif
  
  		/*
  		 * select returned a timeout
  		 */
          if (0 == nrfds) {
  			struct timeval timeAfterSelect;
  			struct timeval deltaTime;
  			gettimeofday(&timeAfterSelect, NULL);
  			/* timeBeforeSelect becomes the delta */
  			timersub(&timeAfterSelect, &timeBeforeSelect, &deltaTime);
  			
  #if defined(LOG_CFSOCKET)
  			fprintf(stdout, "Socket manager received timeout - kicking off expired reads (expired delta %ld, %d)\n", deltaTime.tv_sec, deltaTime.tv_usec);
  #endif
  			
  			__CFSpinLock(&__CFActiveSocketsLock);
  			
  			tempfds = NULL;
  			cnt = CFArrayGetCount(__CFReadSockets);
  			for (idx = 0; idx < cnt; idx++) {
  				CFSocketRef s = (CFSocketRef)CFArrayGetValueAtIndex(__CFReadSockets, idx);
  				if (timerisset(&s->_readBufferTimeout) || s->_leftoverBytes) {
  					CFSocketNativeHandle sock = s->_socket;
  					// We might have an new element in __CFReadSockets that we weren't listening to,
  					// 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 this sockets timeout is less than or equal elapsed time, then signal it */
  					if (INVALID_SOCKET != sock && sockInBounds) {
  #if defined(LOG_CFSOCKET)
  						fprintf(stdout, "Expiring socket %d (delta %ld, %d)\n", sock, s->_readBufferTimeout.tv_sec, s->_readBufferTimeout.tv_usec);
  #endif
  						CFArraySetValueAtIndex(selectedReadSockets, selectedReadSocketsIndex, s);
  						selectedReadSocketsIndex++;
  						/* socket is removed from fds here, will be restored in read handling or in perform function */
  						if (!tempfds) tempfds = (fd_set *)CFDataGetMutableBytePtr(__CFReadSocketsFds);
  						FD_CLR(sock, tempfds);
  					}
  				}
  			}
  			
  			__CFSpinUnlock(&__CFActiveSocketsLock);
  			
  			/* and below, we dispatch through the normal read dispatch mechanism */
  		} 
  		
          if (0 > nrfds) {
              manageSelectError();
              continue;
          }
          if (FD_ISSET(__CFWakeupSocketPair[1], readfds)) {
              recv(__CFWakeupSocketPair[1], (char *)buffer, sizeof(buffer), 0);
  #if defined(LOG_CFSOCKET)
              fprintf(stdout, "socket manager received %c on wakeup socket\n", buffer[0]);
  #endif
          }
          __CFSpinLock(&__CFActiveSocketsLock);
          tempfds = NULL;
          cnt = CFArrayGetCount(__CFWriteSockets);
          for (idx = 0; idx < cnt; idx++) {
              CFSocketRef s = (CFSocketRef)CFArrayGetValueAtIndex(__CFWriteSockets, idx);
              CFSocketNativeHandle sock = s->_socket;
              // We might have an new element in __CFWriteSockets that we weren't listening to,
              // 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) {
                  if (FD_ISSET(sock, writefds)) {
                      CFArraySetValueAtIndex(selectedWriteSockets, selectedWriteSocketsIndex, s);
                      selectedWriteSocketsIndex++;
                      /* socket is removed from fds here, restored by CFSocketReschedule */
                      if (!tempfds) tempfds = (fd_set *)CFDataGetMutableBytePtr(__CFWriteSocketsFds);
                      FD_CLR(sock, tempfds);
  // CFLog(5, CFSTR("Manager: cleared socket %p from write fds"), s);
                  }
              }
          }
          tempfds = NULL;
          cnt = CFArrayGetCount(__CFReadSockets);
          for (idx = 0; idx < cnt; idx++) {
              CFSocketRef s = (CFSocketRef)CFArrayGetValueAtIndex(__CFReadSockets, idx);
              CFSocketNativeHandle sock = s->_socket;
              // We might have an new element in __CFReadSockets that we weren't listening to,
              // 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)) {
                  CFArraySetValueAtIndex(selectedReadSockets, selectedReadSocketsIndex, s);
                  selectedReadSocketsIndex++;
                  /* socket is removed from fds here, will be restored in read handling or in perform function */
                  if (!tempfds) tempfds = (fd_set *)CFDataGetMutableBytePtr(__CFReadSocketsFds);
                  FD_CLR(sock, tempfds);
              }
          }
          __CFSpinUnlock(&__CFActiveSocketsLock);
          
          for (idx = 0; idx < selectedWriteSocketsIndex; idx++) {
              CFSocketRef s = (CFSocketRef)CFArrayGetValueAtIndex(selectedWriteSockets, idx);
              if (kCFNull == (CFNullRef)s) continue;
  #if defined(LOG_CFSOCKET)
              fprintf(stdout, "socket manager signaling socket %d for write\n", s->_socket);
  #endif
              __CFSocketHandleWrite(s, FALSE);
              CFArraySetValueAtIndex(selectedWriteSockets, idx, kCFNull);
          }
          selectedWriteSocketsIndex = 0;
          
          for (idx = 0; idx < selectedReadSocketsIndex; idx++) {
              CFSocketRef s = (CFSocketRef)CFArrayGetValueAtIndex(selectedReadSockets, idx);
              if (kCFNull == (CFNullRef)s) continue;
  #if defined(LOG_CFSOCKET)
              fprintf(stdout, "socket manager signaling socket %d for read\n", s->_socket);
  #endif
              __CFSocketHandleRead(s, nrfds == 0);
              CFArraySetValueAtIndex(selectedReadSockets, idx, kCFNull);
          }
          selectedReadSocketsIndex = 0;
      }
  }
  
  static CFStringRef __CFSocketCopyDescription(CFTypeRef cf) {
      CFSocketRef s = (CFSocketRef)cf;
      CFMutableStringRef result;
      CFStringRef contextDesc = NULL;
      void *contextInfo = NULL;
      CFStringRef (*contextCopyDescription)(const void *info) = NULL;
      result = CFStringCreateMutable(CFGetAllocator(s), 0);
      __CFSocketLock(s);
      void *addr = s->_callout;
  #if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI
      Dl_info info;
      const char *name = (dladdr(addr, &info) && info.dli_saddr == addr && info.dli_sname) ? info.dli_sname : "???";
  #else
      // don't bother trying to figure out callout names
      const char *name = "<unknown>";
  #endif
      CFStringAppendFormat(result, NULL, CFSTR("<CFSocket %p [%p]>{valid = %s, type = %d, socket = %d, socket set count = %ld,\n    callback types = 0x%x, callout = %s (%p), source = %p,\n    run loops = %@,\n    context = "), cf, CFGetAllocator(s), (__CFSocketIsValid(s) ? "Yes" : "No"), (int)(s->_socketType), s->_socket, (long)s->_socketSetCount, __CFSocketCallBackTypes(s), name, addr, s->_source0, s->_runLoops);
      contextInfo = s->_context.info;
      contextCopyDescription = s->_context.copyDescription;
      __CFSocketUnlock(s);
      if (NULL != contextInfo && NULL != contextCopyDescription) {
          contextDesc = (CFStringRef)contextCopyDescription(contextInfo);
      }
      if (NULL == contextDesc) {
          contextDesc = CFStringCreateWithFormat(CFGetAllocator(s), NULL, CFSTR("<CFSocket context %p>"), contextInfo);
      }
      CFStringAppend(result, contextDesc);
      CFStringAppend(result, CFSTR("}"));
      CFRelease(contextDesc);
      return result;
  }
  
  static void __CFSocketDeallocate(CFTypeRef cf) {
      /* Since CFSockets are cached, we can only get here sometime after being invalidated */
      CFSocketRef s = (CFSocketRef)cf;
      if (NULL != s->_address) {
          CFRelease(s->_address);
          s->_address = NULL;
      }
      if (NULL != s->_readBuffer) {
          CFRelease(s->_readBuffer);
          s->_readBuffer = NULL;
      }
  	if (NULL != s->_leftoverBytes) {
  		CFRelease(s->_leftoverBytes);
  		s->_leftoverBytes = NULL;
  	}
      timerclear(&s->_readBufferTimeout);
      s->_bytesToBuffer = 0;
      s->_bytesToBufferPos = 0;
      s->_bytesToBufferReadPos = 0;
      s->_atEOF = true;
  	s->_bufferedReadError = 0;
  }
  
  static CFTypeID __kCFSocketTypeID = _kCFRuntimeNotATypeID;
  
  static const CFRuntimeClass __CFSocketClass = {
      0,
      "CFSocket",
      NULL,      // init
      NULL,      // copy
      __CFSocketDeallocate,
      NULL,      // equal
      NULL,      // hash
      NULL,      // 
      __CFSocketCopyDescription
  };
  
  CFTypeID CFSocketGetTypeID(void) {
      if (_kCFRuntimeNotATypeID == __kCFSocketTypeID) {
  	__kCFSocketTypeID = _CFRuntimeRegisterClass(&__CFSocketClass);
  #if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI
          struct rlimit lim1;
          int ret1 = getrlimit(RLIMIT_NOFILE, &lim1);
          int mib[] = {CTL_KERN, KERN_MAXFILESPERPROC};
          int maxfd = 0;
          size_t len = sizeof(int);
          int ret0 = sysctl(mib, 2, &maxfd, &len, NULL, 0);
          if (0 == ret0 && 0 == ret1 && lim1.rlim_max < maxfd) maxfd = lim1.rlim_max;
          if (0 == ret1 && lim1.rlim_cur < maxfd) {
              struct rlimit lim2 = lim1;
              lim2.rlim_cur += 2304;
              if (maxfd < lim2.rlim_cur) lim2.rlim_cur = maxfd;
              setrlimit(RLIMIT_NOFILE, &lim2);
              // we try, but do not go to extraordinary measures
          }
  #endif
      }
      return __kCFSocketTypeID;
  }
  
  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);
      if (NULL == __CFReadSockets) __CFSocketInitializeSockets();
      __CFSpinUnlock(&__CFActiveSocketsLock);
      __CFSpinLock(&__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);
  			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);
  			CFSocketInvalidate(memory);
  			__CFSpinLock(&__CFAllSocketsLock);
  		}
      }
      memory = (CFSocketRef)_CFRuntimeCreateInstance(allocator, CFSocketGetTypeID(), sizeof(struct __CFSocket) - sizeof(CFRuntimeBase), NULL);
      if (NULL == memory) {
          __CFSpinUnlock(&__CFAllSocketsLock);
          return NULL;
      }
      __CFSocketSetCallBackTypes(memory, callBackTypes);
      if (INVALID_SOCKET != sock) __CFSocketSetValid(memory);
      __CFSocketUnsetWriteSignalled(memory);
      __CFSocketUnsetReadSignalled(memory);
      memory->_f.client = ((callBackTypes & (~kCFSocketConnectCallBack)) & (~kCFSocketWriteCallBack)) | kCFSocketCloseOnInvalidate;
      memory->_f.disabled = 0;
      memory->_f.connected = FALSE;
      memory->_f.writableHint = FALSE;
      memory->_f.closeSignaled = FALSE;
      memory->_lock = CFSpinLockInit;
      memory->_writeLock = CFSpinLockInit;
      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->_address = NULL;
      memory->_peerAddress = NULL;
      memory->_socketSetCount = 0;
      memory->_source0 = NULL;
      if (INVALID_SOCKET != sock) {
          memory->_runLoops = CFArrayCreateMutable(kCFAllocatorSystemDefault, 0, NULL);
      } else {
          memory->_runLoops = NULL;
      }
      memory->_callout = callout;
      memory->_dataQueue = NULL;
      memory->_addressQueue = NULL;
      memory->_context.info = 0;
      memory->_context.retain = 0;
      memory->_context.release = 0;
      memory->_context.copyDescription = 0;
      timerclear(&memory->_readBufferTimeout);
      memory->_readBuffer = NULL;
      memory->_bytesToBuffer = 0;
      memory->_bytesToBufferPos = 0;
      memory->_bytesToBufferReadPos = 0;
      memory->_atEOF = false;
      memory->_bufferedReadError = 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 != context) {
          void *contextInfo = context->retain ? (void *)context->retain(context->info) : context->info;
          __CFSocketLock(memory);
          memory->_context.retain = context->retain;
          memory->_context.release = context->release;
          memory->_context.copyDescription = context->copyDescription;
          memory->_context.info = contextInfo;
          __CFSocketUnlock(memory);
      }
  #if defined(LOG_CFSOCKET)
      CFLog(5, CFSTR("CFSocketCreateWithNative(): created socket %p (%d) with callbacks 0x%x"), memory, memory->_socket, callBackTypes);
  #endif
      return memory;
  }
  
  CFSocketRef CFSocketCreateWithNative(CFAllocatorRef allocator, CFSocketNativeHandle sock, CFOptionFlags callBackTypes, CFSocketCallBack callout, const CFSocketContext *context) {
  	return _CFSocketCreateWithNative(allocator, sock, callBackTypes, callout, context, TRUE);
  }
  
  void CFSocketInvalidate(CFSocketRef s) {
  // CFLog(5, CFSTR("CFSocketInvalidate(%p) starting"), s);
      CHECK_FOR_FORK();
      UInt32 previousSocketManagerIteration;
      __CFGenericValidateType(s, CFSocketGetTypeID());
  #if defined(LOG_CFSOCKET)
      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);
      __CFSocketLock(s);
      if (__CFSocketIsValid(s)) {
          SInt32 idx;
          CFRunLoopSourceRef source0;
          void *contextInfo = NULL;
          void (*contextRelease)(const void *info) = NULL;
          __CFSocketUnsetValid(s);
          __CFSocketUnsetWriteSignalled(s);
          __CFSocketUnsetReadSignalled(s);
          __CFSpinLock(&__CFActiveSocketsLock);
          idx = CFArrayGetFirstIndexOfValue(__CFWriteSockets, CFRangeMake(0, CFArrayGetCount(__CFWriteSockets)), s);
          if (0 <= idx) {
              CFArrayRemoveValueAtIndex(__CFWriteSockets, idx);
              __CFSocketClearFDForWrite(s);
          }
          // No need to clear FD's for V1 sources, since we'll just throw the whole event away
          idx = CFArrayGetFirstIndexOfValue(__CFReadSockets, CFRangeMake(0, CFArrayGetCount(__CFReadSockets)), s);
          if (0 <= idx) {
              CFArrayRemoveValueAtIndex(__CFReadSockets, idx);
              __CFSocketClearFDForRead(s);
          }
          previousSocketManagerIteration = __CFSocketManagerIteration;
          __CFSpinUnlock(&__CFActiveSocketsLock);
          CFDictionaryRemoveValue(__CFAllSockets, (void *)(uintptr_t)(s->_socket));
          if ((s->_f.client & kCFSocketCloseOnInvalidate) != 0) closesocket(s->_socket);
          s->_socket = INVALID_SOCKET;
          if (NULL != s->_peerAddress) {
              CFRelease(s->_peerAddress);
              s->_peerAddress = NULL;
          }
          if (NULL != s->_dataQueue) {
              CFRelease(s->_dataQueue);
              s->_dataQueue = NULL;
          }
          if (NULL != s->_addressQueue) {
              CFRelease(s->_addressQueue);
              s->_addressQueue = NULL;
          }
          s->_socketSetCount = 0;
          
          // we'll need this later
          CFArrayRef runLoops = (CFArrayRef)CFRetain(s->_runLoops);        
          CFRelease(s->_runLoops);
          
          s->_runLoops = NULL;
          source0 = s->_source0;
          s->_source0 = NULL;
          contextInfo = s->_context.info;
          contextRelease = s->_context.release;
          s->_context.info = 0;
          s->_context.retain = 0;
          s->_context.release = 0;
          s->_context.copyDescription = 0;
          __CFSocketUnlock(s);
          
          // Do this after the socket unlock to avoid deadlock (10462525)
          for (idx = CFArrayGetCount(runLoops); idx--;) {
              CFRunLoopWakeUp((CFRunLoopRef)CFArrayGetValueAtIndex(runLoops, idx));
          }
          CFRelease(runLoops);
  
          if (NULL != contextRelease) {
              contextRelease(contextInfo);
          }
          if (NULL != source0) {
              CFRunLoopSourceInvalidate(source0);
              CFRelease(source0);
          }
      } else {
          __CFSocketUnlock(s);
      }
      __CFSpinUnlock(&__CFAllSocketsLock);
      CFRelease(s);
  #if defined(LOG_CFSOCKET)
      CFLog(5, CFSTR("CFSocketInvalidate(%p) done"), s);
  #endif
  }
  
  Boolean CFSocketIsValid(CFSocketRef s) {
      CHECK_FOR_FORK();
      __CFGenericValidateType(s, CFSocketGetTypeID());
      return __CFSocketIsValid(s);
  }
  
  CFSocketNativeHandle CFSocketGetNative(CFSocketRef s) {
      CHECK_FOR_FORK();
      __CFGenericValidateType(s, CFSocketGetTypeID());
      return s->_socket;
  }
  
  CFDataRef CFSocketCopyAddress(CFSocketRef s) {
      CHECK_FOR_FORK();
      CFDataRef result = NULL;
      __CFGenericValidateType(s, CFSocketGetTypeID());
      __CFSocketLock(s);
      __CFSocketEstablishAddress(s);
      if (NULL != s->_address) {
          result = (CFDataRef)CFRetain(s->_address);
      }
      __CFSocketUnlock(s);
  #if defined(LOG_CFSOCKET)
      CFLog(5, CFSTR("CFSocketCopyAddress(): created socket %p address %@"), s, result);
  #endif
      return result;
  }
  
  CFDataRef CFSocketCopyPeerAddress(CFSocketRef s) {
      CHECK_FOR_FORK();
      CFDataRef result = NULL;
      __CFGenericValidateType(s, CFSocketGetTypeID());
      __CFSocketLock(s);
      __CFSocketEstablishPeerAddress(s);
      if (NULL != s->_peerAddress) {
          result = (CFDataRef)CFRetain(s->_peerAddress);
      }
      __CFSocketUnlock(s);
  #if defined(LOG_CFSOCKET)
      CFLog(5, CFSTR("CFSocketCopyAddress(): created socket %p peer address %@"), s, result);
  #endif
      return result;
  }
  
  void CFSocketGetContext(CFSocketRef s, CFSocketContext *context) {
      CHECK_FOR_FORK();
      __CFGenericValidateType(s, CFSocketGetTypeID());
      CFAssert1(0 == context->version, __kCFLogAssertion, "%s(): context version not initialized to 0", __PRETTY_FUNCTION__);
      *context = s->_context;
  }
  
  CFOptionFlags CFSocketGetSocketFlags(CFSocketRef s) {
      CHECK_FOR_FORK();
      __CFGenericValidateType(s, CFSocketGetTypeID());
      return s->_f.client;
  }
  
  void CFSocketSetSocketFlags(CFSocketRef s, CFOptionFlags flags) {
      CHECK_FOR_FORK();
      __CFGenericValidateType(s, CFSocketGetTypeID());
      __CFSocketLock(s);
  #if defined(LOG_CFSOCKET)
          fprintf(stdout, "setting flags for socket %d, from 0x%x to 0x%lx\n", s->_socket, s->_f.client, flags);
  #endif
      s->_f.client = flags;
      __CFSocketUnlock(s);
  // CFLog(5, CFSTR("CFSocketSetSocketFlags(%p, 0x%x)"), s, flags);
  }
  
  void CFSocketDisableCallBacks(CFSocketRef s, CFOptionFlags callBackTypes) {
      CHECK_FOR_FORK();
      Boolean wakeup = false;
      uint8_t readCallBackType;
      __CFGenericValidateType(s, CFSocketGetTypeID());
      __CFSocketLock(s);
      if (__CFSocketIsValid(s) && __CFSocketIsScheduled(s)) {
          callBackTypes &= __CFSocketCallBackTypes(s);
          readCallBackType = __CFSocketReadCallBackType(s);
          s->_f.disabled |= callBackTypes;
  #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);
          if ((readCallBackType == kCFSocketAcceptCallBack) || !__CFSocketIsConnectionOriented(s)) s->_f.connected = TRUE;
          if (((callBackTypes & kCFSocketWriteCallBack) != 0) || (((callBackTypes & kCFSocketConnectCallBack) != 0) && !s->_f.connected)) {
              if (__CFSocketClearFDForWrite(s)) {
                  // do not wake up the socket manager thread if all relevant write callbacks are disabled
                  CFOptionFlags writeCallBacksAvailable = __CFSocketCallBackTypes(s) & (kCFSocketWriteCallBack | kCFSocketConnectCallBack);
                  if (s->_f.connected) writeCallBacksAvailable &= ~kCFSocketConnectCallBack;
                  if ((s->_f.disabled & writeCallBacksAvailable) != writeCallBacksAvailable) wakeup = true;
              }
          }
          if (readCallBackType != kCFSocketNoCallBack && (callBackTypes & readCallBackType) != 0) {
              if (__CFSocketClearFDForRead(s)) {
                  // do not wake up the socket manager thread if callback type is read
                  if (readCallBackType != kCFSocketReadCallBack) wakeup = true;
              }
          }
          __CFSpinUnlock(&__CFActiveSocketsLock);
      }
      __CFSocketUnlock(s);
  }
  
  // "force" means to clear the disabled bits set by DisableCallBacks and always reenable.
  // if (!force) we respect those bits, meaning they may stop us from enabling.
  // In addition, if !force we assume that the sockets have already been added to the
  // __CFReadSockets and __CFWriteSockets arrays.  This is true because the callbacks start
  // enabled when the CFSocket is created (at which time we enable with force).
  // Called with SocketLock held, returns with it released!
  void __CFSocketEnableCallBacks(CFSocketRef s, CFOptionFlags callBackTypes, Boolean force, uint8_t wakeupChar) {
      CHECK_FOR_FORK();
      Boolean wakeup = FALSE;
      if (!callBackTypes) {
          __CFSocketUnlock(s);
          return;
      }
      if (__CFSocketIsValid(s) && __CFSocketIsScheduled(s)) {
          Boolean turnOnWrite = FALSE, turnOnConnect = FALSE, turnOnRead = FALSE;
          uint8_t readCallBackType = __CFSocketReadCallBackType(s);        
          callBackTypes &= __CFSocketCallBackTypes(s);
          if (force) s->_f.disabled &= ~callBackTypes;
  #if defined(LOG_CFSOCKET)
          fprintf(stdout, "rescheduling 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
          /* We will wait for connection only for connection-oriented, non-rendezvous sockets that are not already connected.  Mark others as already connected. */
          if ((readCallBackType == kCFSocketAcceptCallBack) || !__CFSocketIsConnectionOriented(s)) s->_f.connected = TRUE;
  
          // First figure out what to turn on
          if (s->_f.connected || (callBackTypes & kCFSocketConnectCallBack) == 0) {
              // if we want write callbacks and they're not disabled...
              if ((callBackTypes & kCFSocketWriteCallBack) != 0 && (s->_f.disabled & kCFSocketWriteCallBack) == 0) turnOnWrite = TRUE;
          } else {
              // if we want connect callbacks and they're not disabled...
              if ((callBackTypes & kCFSocketConnectCallBack) != 0 && (s->_f.disabled & kCFSocketConnectCallBack) == 0) turnOnConnect = TRUE;
          }
          // if we want read callbacks and they're not disabled...
          if (readCallBackType != kCFSocketNoCallBack && (callBackTypes & readCallBackType) != 0 && (s->_f.disabled & kCFSocketReadCallBack) == 0) turnOnRead = TRUE;
  
          // Now turn on the callbacks we've determined that we want on
          if (turnOnRead || turnOnWrite || turnOnConnect) {
              __CFSpinLock(&__CFActiveSocketsLock);
              if (turnOnWrite || turnOnConnect) {
                  if (force) {
                      SInt32 idx = CFArrayGetFirstIndexOfValue(__CFWriteSockets, CFRangeMake(0, CFArrayGetCount(__CFWriteSockets)), s);
                      if (kCFNotFound == idx) CFArrayAppendValue(__CFWriteSockets, s);
  //                     if (kCFNotFound == idx) CFLog(5, CFSTR("__CFSocketEnableCallBacks: put %p in __CFWriteSockets list due to force and non-presence"), s);
                  }
                  if (__CFSocketSetFDForWrite(s)) wakeup = true;
              }
              if (turnOnRead) {
                  if (force) {
                      SInt32 idx = CFArrayGetFirstIndexOfValue(__CFReadSockets, CFRangeMake(0, CFArrayGetCount(__CFReadSockets)), s);
                      if (kCFNotFound == idx) CFArrayAppendValue(__CFReadSockets, s);
                  }
                  if (__CFSocketSetFDForRead(s)) wakeup = true;
              }
              __CFSpinUnlock(&__CFActiveSocketsLock);
          }
      }
      __CFSocketUnlock(s);
  }
  
  void CFSocketEnableCallBacks(CFSocketRef s, CFOptionFlags callBackTypes) {
      CHECK_FOR_FORK();
      __CFGenericValidateType(s, CFSocketGetTypeID());
      __CFSocketLock(s);
      __CFSocketEnableCallBacks(s, callBackTypes, TRUE, 'r');
  // CFLog(5, CFSTR("CFSocketEnableCallBacks(%p, 0x%x) done"), s, callBackTypes);
  }
  
  static void __CFSocketSchedule(void *info, CFRunLoopRef rl, CFStringRef mode) {
      CFSocketRef s = (CFSocketRef)info;
      __CFSocketLock(s);
      //??? also need to arrange delivery of all pending data
      if (__CFSocketIsValid(s)) {
          CFMutableArrayRef runLoopsOrig = s->_runLoops;
          CFMutableArrayRef runLoopsCopy = CFArrayCreateMutableCopy(kCFAllocatorSystemDefault, 0, s->_runLoops);
          CFArrayAppendValue(runLoopsCopy, rl);
          s->_runLoops = runLoopsCopy;
          CFRelease(runLoopsOrig);
          s->_socketSetCount++;
          // Since the v0 source is listened to on the SocketMgr thread, no matter how many modes it
          // is added to we just need to enable it there once (and _socketSetCount gives us a refCount
          // to know when we can finally disable it).
          if (1 == s->_socketSetCount) {
  #if defined(LOG_CFSOCKET)
              fprintf(stdout, "scheduling socket %d\n", s->_socket);
  #endif
  // CFLog(5, CFSTR("__CFSocketSchedule(%p, %p, %p)"), s, rl, mode);
              __CFSocketEnableCallBacks(s, __CFSocketCallBackTypes(s), TRUE, 's');  // unlocks s
          } else
              __CFSocketUnlock(s);
      } else
          __CFSocketUnlock(s);
  }
  
  static void __CFSocketCancel(void *info, CFRunLoopRef rl, CFStringRef mode) {
      CFSocketRef s = (CFSocketRef)info;
      SInt32 idx;
      __CFSocketLock(s);
      s->_socketSetCount--;
      if (0 == s->_socketSetCount) {
          __CFSpinLock(&__CFActiveSocketsLock);
          idx = CFArrayGetFirstIndexOfValue(__CFWriteSockets, CFRangeMake(0, CFArrayGetCount(__CFWriteSockets)), s);
          if (0 <= idx) {
  // CFLog(5, CFSTR("__CFSocketCancel: removing %p from __CFWriteSockets list"), s);
              CFArrayRemoveValueAtIndex(__CFWriteSockets, idx);
              __CFSocketClearFDForWrite(s);
          }
          idx = CFArrayGetFirstIndexOfValue(__CFReadSockets, CFRangeMake(0, CFArrayGetCount(__CFReadSockets)), s);
          if (0 <= idx) {
              CFArrayRemoveValueAtIndex(__CFReadSockets, idx);
              __CFSocketClearFDForRead(s);
          }
          __CFSpinUnlock(&__CFActiveSocketsLock);
      }
      if (NULL != s->_runLoops) {
          CFMutableArrayRef runLoopsOrig = s->_runLoops;
          CFMutableArrayRef runLoopsCopy = CFArrayCreateMutableCopy(kCFAllocatorSystemDefault, 0, s->_runLoops);
          idx = CFArrayGetFirstIndexOfValue(runLoopsCopy, CFRangeMake(0, CFArrayGetCount(runLoopsCopy)), rl);
          if (0 <= idx) CFArrayRemoveValueAtIndex(runLoopsCopy, idx);
          s->_runLoops = runLoopsCopy;
          CFRelease(runLoopsOrig);
      }
      __CFSocketUnlock(s);
  }
  
  // Note:  must be called with socket lock held, then returns with it released
  // Used by both the v0 and v1 RunLoopSource perform routines
  static void __CFSocketDoCallback(CFSocketRef s, CFDataRef data, CFDataRef address, CFSocketNativeHandle sock) {
      CFSocketCallBack callout = NULL;
      void *contextInfo = NULL;
      SInt32 errorCode = 0;
      Boolean readSignalled = false, writeSignalled = false, connectSignalled = false, calledOut = false;
      uint8_t readCallBackType, callBackTypes;
      
      callBackTypes = __CFSocketCallBackTypes(s);
      readCallBackType = __CFSocketReadCallBackType(s);
      readSignalled = __CFSocketIsReadSignalled(s);
      writeSignalled = __CFSocketIsWriteSignalled(s);
      connectSignalled = writeSignalled && !s->_f.connected;
      __CFSocketUnsetReadSignalled(s);
      __CFSocketUnsetWriteSignalled(s);
      callout = s->_callout;
      contextInfo = s->_context.info;
  #if defined(LOG_CFSOCKET)
      fprintf(stdout, "entering perform for socket %d with read signalled %d write signalled %d connect signalled %d callback types %d\n", s->_socket, readSignalled, writeSignalled, connectSignalled, callBackTypes);
  #endif
      if (writeSignalled) {
          errorCode = s->_errorCode;
          s->_f.connected = TRUE;
      }
      __CFSocketUnlock(s);
      if ((callBackTypes & kCFSocketConnectCallBack) != 0) {
          if (connectSignalled && (!calledOut || CFSocketIsValid(s))) {
  // CFLog(5, CFSTR("__CFSocketPerformV0(%p) doing connect callback, error: %d"), s, errorCode);
              if (errorCode) {
  #if defined(LOG_CFSOCKET)
                  fprintf(stdout, "perform calling out error %ld to socket %d\n", (long)errorCode, s->_socket);
  #endif
                  if (callout) callout(s, kCFSocketConnectCallBack, NULL, &errorCode, contextInfo);
                  calledOut = true;
              } else {
  #if defined(LOG_CFSOCKET)
                  fprintf(stdout, "perform calling out connect to socket %d\n", s->_socket);
  #endif
                  if (callout) callout(s, kCFSocketConnectCallBack, NULL, NULL, contextInfo);
                  calledOut = true;
              }
          }
      }
      if (kCFSocketDataCallBack == readCallBackType) {
          if (NULL != data && (!calledOut || CFSocketIsValid(s))) {
              SInt32 datalen = CFDataGetLength(data);
  #if defined(LOG_CFSOCKET)
              fprintf(stdout, "perform calling out data of length %ld to socket %d\n", (long)datalen, s->_socket);
  #endif
              if (callout) callout(s, kCFSocketDataCallBack, address, data, contextInfo);
              calledOut = true;
              if (0 == datalen) CFSocketInvalidate(s);
          }
      } else if (kCFSocketAcceptCallBack == readCallBackType) {
          if (INVALID_SOCKET != sock && (!calledOut || CFSocketIsValid(s))) {
  #if defined(LOG_CFSOCKET)
              fprintf(stdout, "perform calling out accept of socket %d to socket %d\n", sock, s->_socket);
  #endif
              if (callout) callout(s, kCFSocketAcceptCallBack, address, &sock, contextInfo);
              calledOut = true;
          }
      } else if (kCFSocketReadCallBack == readCallBackType) {
          if (readSignalled && (!calledOut || CFSocketIsValid(s))) {
  #if defined(LOG_CFSOCKET)
              fprintf(stdout, "perform calling out read to socket %d\n", s->_socket);
  #endif
  // CFLog(5, CFSTR("__CFSocketPerformV0(%p) doing read callback"), s);
              if (callout) callout(s, kCFSocketReadCallBack, NULL, NULL, contextInfo);
              calledOut = true;
          }
      }
      if ((callBackTypes & kCFSocketWriteCallBack) != 0) {
          if (writeSignalled && !errorCode && (!calledOut || CFSocketIsValid(s))) {
  #if defined(LOG_CFSOCKET)
              fprintf(stdout, "perform calling out write to socket %d\n", s->_socket);
  #endif
  // CFLog(5, CFSTR("__CFSocketPerformV0(%p) doing write callback"), s);
              if (callout) callout(s, kCFSocketWriteCallBack, NULL, NULL, contextInfo);
              calledOut = true;
          }
      }
  }
  
  static void __CFSocketPerformV0(void *info) {
      CFSocketRef s = (CFSocketRef)info;
      CFDataRef data = NULL;
      CFDataRef address = NULL;
      CFSocketNativeHandle sock = INVALID_SOCKET;
      uint8_t readCallBackType, callBackTypes;
      CFRunLoopRef rl = NULL;
  // CFLog(5, CFSTR("__CFSocketPerformV0(%p) starting"), s);
  
      __CFSocketLock(s);
      if (!__CFSocketIsValid(s)) {
          __CFSocketUnlock(s);
          return;
      }
      callBackTypes = __CFSocketCallBackTypes(s);
      readCallBackType = __CFSocketReadCallBackType(s);
      CFOptionFlags callBacksSignalled = 0;
      if (__CFSocketIsReadSignalled(s)) callBacksSignalled |= readCallBackType;
      if (__CFSocketIsWriteSignalled(s)) callBacksSignalled |= kCFSocketWriteCallBack;
  
      if (kCFSocketDataCallBack == readCallBackType) {
          if (NULL != s->_dataQueue && 0 < CFArrayGetCount(s->_dataQueue)) {
              data = (CFDataRef)CFArrayGetValueAtIndex(s->_dataQueue, 0);
              CFRetain(data);
              CFArrayRemoveValueAtIndex(s->_dataQueue, 0);
              address = (CFDataRef)CFArrayGetValueAtIndex(s->_addressQueue, 0);
              CFRetain(address);
              CFArrayRemoveValueAtIndex(s->_addressQueue, 0);
          }
      } else if (kCFSocketAcceptCallBack == readCallBackType) {
          if (NULL != s->_dataQueue && 0 < CFArrayGetCount(s->_dataQueue)) {
              sock = (CFSocketNativeHandle)(uintptr_t)CFArrayGetValueAtIndex(s->_dataQueue, 0);
              CFArrayRemoveValueAtIndex(s->_dataQueue, 0);
              address = (CFDataRef)CFArrayGetValueAtIndex(s->_addressQueue, 0);
              CFRetain(address);
              CFArrayRemoveValueAtIndex(s->_addressQueue, 0);
          }
      }
  
      __CFSocketDoCallback(s, data, address, sock);	// does __CFSocketUnlock(s)
      if (NULL != data) CFRelease(data);
      if (NULL != address) CFRelease(address);
  
      __CFSocketLock(s);
      if (__CFSocketIsValid(s) && kCFSocketNoCallBack != readCallBackType) {
          // if there's still more data, we want to wake back up right away
          if ((kCFSocketDataCallBack == readCallBackType || kCFSocketAcceptCallBack == readCallBackType) && NULL != s->_dataQueue && 0 < CFArrayGetCount(s->_dataQueue)) {
  #if defined(LOG_CFSOCKET)
              fprintf(stdout, "perform short-circuit signaling source for 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
              CFRunLoopSourceSignal(s->_source0);
              CFMutableArrayRef runLoopsOrig = (CFMutableArrayRef)CFRetain(s->_runLoops);
              CFMutableArrayRef runLoopsCopy = CFArrayCreateMutableCopy(kCFAllocatorSystemDefault, 0, s->_runLoops);
              CFRunLoopSourceRef source0 = s->_source0;
              if (NULL != source0 && !CFRunLoopSourceIsValid(source0)) {
                  source0 = NULL;
              }
              if (source0) CFRetain(source0);
              __CFSocketUnlock(s);
              rl = __CFSocketCopyRunLoopToWakeUp(source0, runLoopsCopy);
              if (source0) CFRelease(source0);
              __CFSocketLock(s);
              if (runLoopsOrig == s->_runLoops) {
                  s->_runLoops = runLoopsCopy;
                  runLoopsCopy = NULL;
                  CFRelease(runLoopsOrig);
              }
              CFRelease(runLoopsOrig);
              if (runLoopsCopy) CFRelease(runLoopsCopy);
          }
      }
      // Only reenable callbacks that are auto-reenabled
      __CFSocketEnableCallBacks(s, callBacksSignalled & s->_f.client, FALSE, 'p');  // unlocks s
  
      if (NULL != rl) {
          CFRunLoopWakeUp(rl);
          CFRelease(rl);
      }
  // CFLog(5, CFSTR("__CFSocketPerformV0(%p) done"), s);
  }
  
  CFRunLoopSourceRef CFSocketCreateRunLoopSource(CFAllocatorRef allocator, CFSocketRef s, CFIndex order) {
      CHECK_FOR_FORK();
      CFRunLoopSourceRef result = NULL;
      __CFGenericValidateType(s, CFSocketGetTypeID());
      __CFSocketLock(s);
      if (__CFSocketIsValid(s)) {
          if (NULL != s->_source0 && !CFRunLoopSourceIsValid(s->_source0)) {
              CFRelease(s->_source0);
              s->_source0 = NULL;
          }
          if (NULL == s->_source0) {
              CFRunLoopSourceContext context;
              context.version = 0;
              context.info = s;
              context.retain = CFRetain;
              context.release = CFRelease;
              context.copyDescription = CFCopyDescription;
              context.equal = CFEqual;
              context.hash = CFHash;
              context.schedule = __CFSocketSchedule;
              context.cancel = __CFSocketCancel;
              context.perform = __CFSocketPerformV0;
              s->_source0 = CFRunLoopSourceCreate(allocator, order, &context);
          }
          CFRetain(s->_source0);        /* This retain is for the receiver */
          result = s->_source0;
      }
      __CFSocketUnlock(s);
      return result;
  }
  
  #endif /* NEW_SOCKET */
  
  
  
  static uint16_t __CFSocketDefaultNameRegistryPortNumber = 2454;
  
  CONST_STRING_DECL(kCFSocketCommandKey, "Command")
  CONST_STRING_DECL(kCFSocketNameKey, "Name")
  CONST_STRING_DECL(kCFSocketValueKey, "Value")
  CONST_STRING_DECL(kCFSocketResultKey, "Result")
  CONST_STRING_DECL(kCFSocketErrorKey, "Error")
  CONST_STRING_DECL(kCFSocketRegisterCommand, "Register")
  CONST_STRING_DECL(kCFSocketRetrieveCommand, "Retrieve")
  CONST_STRING_DECL(__kCFSocketRegistryRequestRunLoopMode, "CFSocketRegistryRequest")
  
  static CFSpinLock_t __CFSocketWriteLock_ = CFSpinLockInit;
  //#warning can only send on one socket at a time now
  
  CF_INLINE void __CFSocketWriteLock(CFSocketRef s) {
      __CFSpinLock(& __CFSocketWriteLock_);
  }
  
  CF_INLINE void __CFSocketWriteUnlock(CFSocketRef s) {
      __CFSpinUnlock(& __CFSocketWriteLock_);
  }
  
  #if NEW_SOCKET
  
  CF_INLINE CFIndex __CFSocketFdGetSize(CFDataRef fdSet) {
      return NBBY * CFDataGetLength(fdSet);
  }
  
  CF_INLINE Boolean __CFSocketFdSet(CFSocketNativeHandle sock, CFMutableDataRef fdSet) {
      /* returns true if a change occurred, false otherwise */
      Boolean retval = false;
      if (INVALID_SOCKET != sock && 0 <= sock) {
          CFIndex numFds = NBBY * CFDataGetLength(fdSet);
          fd_mask *fds_bits;
          if (sock >= numFds) {
              CFIndex oldSize = numFds / NFDBITS, newSize = (sock + NFDBITS) / NFDBITS, changeInBytes = (newSize - oldSize) * sizeof(fd_mask);
              CFDataIncreaseLength(fdSet, changeInBytes);
              fds_bits = (fd_mask *)CFDataGetMutableBytePtr(fdSet);
              memset(fds_bits + oldSize, 0, changeInBytes);
          } else {
              fds_bits = (fd_mask *)CFDataGetMutableBytePtr(fdSet);
          }
          if (!FD_ISSET(sock, (fd_set *)fds_bits)) {
              retval = true;
              FD_SET(sock, (fd_set *)fds_bits);
          }
      }
      return retval;
  }
  
  #endif
  
  //??? need timeout, error handling, retries
  CFSocketError CFSocketSendData(CFSocketRef s, CFDataRef address, CFDataRef data, CFTimeInterval timeout) {
      CHECK_FOR_FORK();
      const uint8_t *dataptr, *addrptr = NULL;
      SInt32 datalen, addrlen = 0, size = 0;
      CFSocketNativeHandle sock = INVALID_SOCKET;
      struct timeval tv;
      __CFGenericValidateType(s, CFSocketGetTypeID());
      if (address) {
          addrptr = CFDataGetBytePtr(address);
          addrlen = CFDataGetLength(address);
      }
      dataptr = CFDataGetBytePtr(data);
      datalen = CFDataGetLength(data);
      if (CFSocketIsValid(s)) sock = CFSocketGetNative(s);
      if (INVALID_SOCKET != sock) {
          CFRetain(s);
          __CFSocketWriteLock(s);
          tv.tv_sec = (timeout <= 0.0 || (CFTimeInterval)INT_MAX <= timeout) ? INT_MAX : (int)floor(timeout);
          tv.tv_usec = (int)floor(1.0e+6 * (timeout - floor(timeout)));
          setsockopt(sock, SOL_SOCKET, SO_SNDTIMEO, (char *)&tv, sizeof(tv));	// cast for WinSock bad API
          if (NULL != addrptr && 0 < addrlen) {
              size = sendto(sock, (char *)dataptr, datalen, 0, (struct sockaddr *)addrptr, addrlen);
          } else {
              size = send(sock, (char *)dataptr, datalen, 0);
          }
  #if defined(LOG_CFSOCKET)
          fprintf(stdout, "wrote %ld bytes to socket %d\n", (long)size, sock);
  #endif
          __CFSocketWriteUnlock(s);
          CFRelease(s);
      }
      return (size > 0) ? kCFSocketSuccess : kCFSocketError;
  }
  
  CFSocketError CFSocketSetAddress(CFSocketRef s, CFDataRef address) {
      CHECK_FOR_FORK();
      struct sockaddr *name;
      socklen_t namelen;
      __CFGenericValidateType(s, CFSocketGetTypeID());
      if (NULL == address) return kCFSocketError;
      if (!CFSocketIsValid(s)) return kCFSocketError;
      
      name = (struct sockaddr *)CFDataGetBytePtr(address);
      namelen = (socklen_t)CFDataGetLength(address);
      if (!name || namelen <= 0) return kCFSocketError;
      
      CFSocketNativeHandle sock = CFSocketGetNative(s);
  #if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI
      // Verify that the namelen is correct. If not, we have to fix it up. Developers will often incorrectly use 0 or strlen(path). See 9217961 and the second half of 9098274.
      // Max size is a size byte, plus family byte, plus path of 255, plus a null byte.
      char newName[255];
      if (namelen > 2 && name->sa_family == AF_UNIX) {
          // Don't use the SUN_LEN macro, because strnlen is safer and we know the max length of the string (from CFData, minus 2 bytes for len and addr)
          socklen_t realLength = (sizeof(*((struct sockaddr_un *)name)) - sizeof(((struct sockaddr_un *)name)->sun_path) + strnlen(((struct sockaddr_un *)name)->sun_path, namelen - 2));
          if (realLength > 255) return kCFSocketError;
          
          // For a UNIX domain socket, we must pass the value of name.sun_len to bind in order for getsockname() to return a result that makes sense.
          namelen = (socklen_t)(((struct sockaddr_un *)name)->sun_len);
          
          if (realLength != namelen) {
              // We got a different answer for length than was supplied by the caller. Fix it up so we don't end up truncating the path.
              CFLog(kCFLogLevelWarning, CFSTR("WARNING: The sun_len field of a sockaddr_un structure passed to CFSocketSetAddress was not set correctly using the SUN_LEN macro."));
              memcpy(newName, name, realLength);
              namelen = realLength;
              ((struct sockaddr_un *)newName)->sun_len = realLength;
              name = (struct sockaddr *)newName;
          }
      }
  #endif
      int result = bind(sock, name, namelen);
      if (0 == result) {
          listen(sock, 256);
      }
      //??? should return errno
      return (CFIndex)result;
  }
  
  CFSocketError CFSocketConnectToAddress(CFSocketRef s, CFDataRef address, CFTimeInterval timeout) {
      CHECK_FOR_FORK();
      //??? need error handling, retries
      const uint8_t *name;
      SInt32 namelen, result = -1, connect_err = 0, select_err = 0;
      UInt32 yes = 1, no = 0;
      Boolean wasBlocking = true;
  
      __CFGenericValidateType(s, CFSocketGetTypeID());
      if (!CFSocketIsValid(s)) return kCFSocketError;
      name = CFDataGetBytePtr(address);
      namelen = CFDataGetLength(address);
      if (!name || namelen <= 0) return kCFSocketError;
      CFSocketNativeHandle sock = CFSocketGetNative(s);
      {
  #if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI
          SInt32 flags = fcntl(sock, F_GETFL, 0);
          if (flags >= 0) wasBlocking = ((flags & O_NONBLOCK) == 0);
          if (wasBlocking && (timeout > 0.0 || timeout < 0.0)) ioctlsocket(sock, FIONBIO, (u_long *)&yes);
  #else
          // You can set but not get this flag in WIN32, so assume it was in non-blocking mode.
          // The downside is that when we leave this routine we'll leave it non-blocking,
          // whether it started that way or not.
          SInt32 flags = 0;
          if (timeout > 0.0 || timeout < 0.0) ioctlsocket(sock, FIONBIO, (u_long *)&yes);
          wasBlocking = false;
  #endif
          result = connect(sock, (struct sockaddr *)name, namelen);
          if (result != 0) {
              connect_err = __CFSocketLastError();
  #if DEPLOYMENT_TARGET_WINDOWS
              if (connect_err == WSAEWOULDBLOCK) connect_err = EINPROGRESS;
  #endif
          }
  #if defined(LOG_CFSOCKET)
          fprintf(stdout, "connection attempt returns %d error %d on socket %d (flags 0x%x blocking %d)\n", (int) result, (int) connect_err, sock, (int) flags, wasBlocking);
  #endif
          if (EINPROGRESS == connect_err && timeout >= 0.0) {
              /* select on socket */
              SInt32 nrfds;
              int error_size = sizeof(select_err);
              struct timeval tv;
              CFMutableDataRef fds = CFDataCreateMutable(kCFAllocatorSystemDefault, 0);
              __CFSocketFdSet(sock, fds);
              tv.tv_sec = (timeout <= 0.0 || (CFTimeInterval)INT_MAX <= timeout) ? INT_MAX : (int)floor(timeout);
              tv.tv_usec = (int)floor(1.0e+6 * (timeout - floor(timeout)));
              nrfds = select(__CFSocketFdGetSize(fds), NULL, (fd_set *)CFDataGetMutableBytePtr(fds), NULL, &tv);
              if (nrfds < 0) {
                  select_err = __CFSocketLastError();
                  result = -1;
              } else if (nrfds == 0) {
                  result = -2;
              } else {
                  if (0 != getsockopt(sock, SOL_SOCKET, SO_ERROR, (char *)&select_err, (socklen_t *)&error_size)) select_err = 0;
                  result = (select_err == 0) ? 0 : -1;
              }
              CFRelease(fds);
  #if defined(LOG_CFSOCKET)
              fprintf(stdout, "timed connection attempt %s on socket %d, result %d, select returns %d error %d\n", (result == 0) ? "succeeds" : "fails", sock, (int) result, (int) nrfds, (int) select_err);
  #endif
          }
          if (wasBlocking && (timeout > 0.0 || timeout < 0.0)) ioctlsocket(sock, FIONBIO, (u_long *)&no);
          if (EINPROGRESS == connect_err && timeout < 0.0) {
              result = 0;
  #if defined(LOG_CFSOCKET)
              fprintf(stdout, "connection attempt continues in background on socket %d\n", sock);
  #endif
          }
      }
      //??? should return errno
      return result;
  }
  
  CFSocketRef CFSocketCreate(CFAllocatorRef allocator, SInt32 protocolFamily, SInt32 socketType, SInt32 protocol, CFOptionFlags callBackTypes, CFSocketCallBack callout, const CFSocketContext *context) {
      CHECK_FOR_FORK();
      CFSocketNativeHandle sock = INVALID_SOCKET;
      CFSocketRef s = NULL;
      if (0 >= protocolFamily) protocolFamily = PF_INET;
      if (PF_INET == protocolFamily) {
          if (0 >= socketType) socketType = SOCK_STREAM;
          if (0 >= protocol && SOCK_STREAM == socketType) protocol = IPPROTO_TCP;
          if (0 >= protocol && SOCK_DGRAM == socketType) protocol = IPPROTO_UDP;
      }
  #if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI
      if (PF_LOCAL == protocolFamily && 0 >= socketType) socketType = SOCK_STREAM;
  #endif
  #if DEPLOYMENT_TARGET_WINDOWS
      // make sure we've called proper Win32 startup facilities before socket()
      __CFSocketInitializeWinSock();
  #endif
      sock = socket(protocolFamily, socketType, protocol);
      if (INVALID_SOCKET != sock) {
          s = CFSocketCreateWithNative(allocator, sock, callBackTypes, callout, context);
      }
      return s;
  }
  
  CFSocketRef CFSocketCreateWithSocketSignature(CFAllocatorRef allocator, const CFSocketSignature *signature, CFOptionFlags callBackTypes, CFSocketCallBack callout, const CFSocketContext *context) {
      CHECK_FOR_FORK();
      CFSocketRef s = CFSocketCreate(allocator, signature->protocolFamily, signature->socketType, signature->protocol, callBackTypes, callout, context);
      if (NULL != s && (!CFSocketIsValid(s) || kCFSocketSuccess != CFSocketSetAddress(s, signature->address))) {
          CFSocketInvalidate(s);
          CFRelease(s);
          s = NULL;
      }
      return s;
  }
  
  CFSocketRef CFSocketCreateConnectedToSocketSignature(CFAllocatorRef allocator, const CFSocketSignature *signature, CFOptionFlags callBackTypes, CFSocketCallBack callout, const CFSocketContext *context, CFTimeInterval timeout) {
      CHECK_FOR_FORK();
      CFSocketRef s = CFSocketCreate(allocator, signature->protocolFamily, signature->socketType, signature->protocol, callBackTypes, callout, context);
      if (NULL != s && (!CFSocketIsValid(s) || kCFSocketSuccess != CFSocketConnectToAddress(s, signature->address, timeout))) {
          CFSocketInvalidate(s);
          CFRelease(s);
          s = NULL;
      }
      return s;
  }
  
  typedef struct {
      CFSocketError *error;
      CFPropertyListRef *value;
      CFDataRef *address;
  } __CFSocketNameRegistryResponse;
  
  static void __CFSocketHandleNameRegistryReply(CFSocketRef s, CFSocketCallBackType type, CFDataRef address, const void *data, void *info) {
      CFDataRef replyData = (CFDataRef)data;
      __CFSocketNameRegistryResponse *response = (__CFSocketNameRegistryResponse *)info;
      CFDictionaryRef replyDictionary = NULL;
      CFPropertyListRef value;
      replyDictionary = (CFDictionaryRef)CFPropertyListCreateFromXMLData(kCFAllocatorSystemDefault, replyData, kCFPropertyListImmutable, NULL);
      if (NULL != response->error) *(response->error) = kCFSocketError;
      if (NULL != replyDictionary) {
          if (CFGetTypeID((CFTypeRef)replyDictionary) == CFDictionaryGetTypeID() && NULL != (value = CFDictionaryGetValue(replyDictionary, kCFSocketResultKey))) {
              if (NULL != response->error) *(response->error) = kCFSocketSuccess;
              if (NULL != response->value) *(response->value) = CFRetain(value);
              if (NULL != response->address) *(response->address) = address ? CFDataCreateCopy(kCFAllocatorSystemDefault, address) : NULL;
          }
          CFRelease(replyDictionary);
      }
      CFSocketInvalidate(s);
  }
  
  static void __CFSocketSendNameRegistryRequest(CFSocketSignature *signature, CFDictionaryRef requestDictionary, __CFSocketNameRegistryResponse *response, CFTimeInterval timeout) {
      CFDataRef requestData = NULL;
      CFSocketContext context = {0, response, NULL, NULL, NULL};
      CFSocketRef s = NULL;
      CFRunLoopSourceRef source = NULL;
      if (NULL != response->error) *(response->error) = kCFSocketError;
      requestData = CFPropertyListCreateXMLData(kCFAllocatorSystemDefault, requestDictionary);
      if (NULL != requestData) {
          if (NULL != response->error) *(response->error) = kCFSocketTimeout;
          s = CFSocketCreateConnectedToSocketSignature(kCFAllocatorSystemDefault, signature, kCFSocketDataCallBack, __CFSocketHandleNameRegistryReply, &context, timeout);
          if (NULL != s) {
              if (kCFSocketSuccess == CFSocketSendData(s, NULL, requestData, timeout)) {
                  source = CFSocketCreateRunLoopSource(kCFAllocatorSystemDefault, s, 0);
                  CFRunLoopAddSource(CFRunLoopGetCurrent(), source, __kCFSocketRegistryRequestRunLoopMode);
                  CFRunLoopRunInMode(__kCFSocketRegistryRequestRunLoopMode, timeout, false);
                  CFRelease(source);
              }
              CFSocketInvalidate(s);
              CFRelease(s);
          }
          CFRelease(requestData);
      }
  }
  
  static void __CFSocketValidateSignature(const CFSocketSignature *providedSignature, CFSocketSignature *signature, uint16_t defaultPortNumber) {
      struct sockaddr_in sain, *sainp;
      memset(&sain, 0, sizeof(sain));
  #if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI
      sain.sin_len = sizeof(sain);
  #endif
      sain.sin_family = AF_INET;
      sain.sin_port = htons(__CFSocketDefaultNameRegistryPortNumber);
      sain.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
      if (NULL == providedSignature) {
          signature->protocolFamily = PF_INET;
          signature->socketType = SOCK_STREAM;
          signature->protocol = IPPROTO_TCP;
          signature->address = CFDataCreate(kCFAllocatorSystemDefault, (uint8_t *)&sain, sizeof(sain));
      } else {
          signature->protocolFamily = providedSignature->protocolFamily;
          signature->socketType = providedSignature->socketType;
          signature->protocol = providedSignature->protocol;
          if (0 >= signature->protocolFamily) signature->protocolFamily = PF_INET;
          if (PF_INET == signature->protocolFamily) {
              if (0 >= signature->socketType) signature->socketType = SOCK_STREAM;
              if (0 >= signature->protocol && SOCK_STREAM == signature->socketType) signature->protocol = IPPROTO_TCP;
              if (0 >= signature->protocol && SOCK_DGRAM == signature->socketType) signature->protocol = IPPROTO_UDP;
          }
          if (NULL == providedSignature->address) {
              signature->address = CFDataCreate(kCFAllocatorSystemDefault, (uint8_t *)&sain, sizeof(sain));
          } else {
              sainp = (struct sockaddr_in *)CFDataGetBytePtr(providedSignature->address);
              if ((int)sizeof(struct sockaddr_in) <= CFDataGetLength(providedSignature->address) && (AF_INET == sainp->sin_family || 0 == sainp->sin_family)) {
  #if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI
                  sain.sin_len = sizeof(sain);
  #endif
                  sain.sin_family = AF_INET;
                  sain.sin_port = sainp->sin_port;
                  if (0 == sain.sin_port) sain.sin_port = htons(defaultPortNumber);
                  sain.sin_addr.s_addr = sainp->sin_addr.s_addr;
                  if (htonl(INADDR_ANY) == sain.sin_addr.s_addr) sain.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
                  signature->address = CFDataCreate(kCFAllocatorSystemDefault, (uint8_t *)&sain, sizeof(sain));
              } else {
                  signature->address = (CFDataRef)CFRetain(providedSignature->address);
              }
          }
      }
  }
  
  CFSocketError CFSocketRegisterValue(const CFSocketSignature *nameServerSignature, CFTimeInterval timeout, CFStringRef name, CFPropertyListRef value) {
      CFSocketSignature signature;
      CFMutableDictionaryRef dictionary = CFDictionaryCreateMutable(kCFAllocatorSystemDefault, 3, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
      CFSocketError retval = kCFSocketError;
      __CFSocketNameRegistryResponse response = {&retval, NULL, NULL};
      CFDictionaryAddValue(dictionary, kCFSocketCommandKey, kCFSocketRegisterCommand);
      CFDictionaryAddValue(dictionary, kCFSocketNameKey, name);
      if (NULL != value) CFDictionaryAddValue(dictionary, kCFSocketValueKey, value);
      __CFSocketValidateSignature(nameServerSignature, &signature, __CFSocketDefaultNameRegistryPortNumber);
      __CFSocketSendNameRegistryRequest(&signature, dictionary, &response, timeout);
      CFRelease(dictionary);
      CFRelease(signature.address);
      return retval;
  }
  
  CFSocketError CFSocketCopyRegisteredValue(const CFSocketSignature *nameServerSignature, CFTimeInterval timeout, CFStringRef name, CFPropertyListRef *value, CFDataRef *serverAddress) {
      CFSocketSignature signature;
      CFMutableDictionaryRef dictionary = CFDictionaryCreateMutable(kCFAllocatorSystemDefault, 2, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
      CFSocketError retval = kCFSocketError;
      __CFSocketNameRegistryResponse response = {&retval, value, serverAddress};
      CFDictionaryAddValue(dictionary, kCFSocketCommandKey, kCFSocketRetrieveCommand);
      CFDictionaryAddValue(dictionary, kCFSocketNameKey, name);
      __CFSocketValidateSignature(nameServerSignature, &signature, __CFSocketDefaultNameRegistryPortNumber);
      __CFSocketSendNameRegistryRequest(&signature, dictionary, &response, timeout);
      CFRelease(dictionary);
      CFRelease(signature.address);
      return retval;
  }
  
  CFSocketError CFSocketRegisterSocketSignature(const CFSocketSignature *nameServerSignature, CFTimeInterval timeout, CFStringRef name, const CFSocketSignature *signature) {
      CFSocketSignature validatedSignature;
      CFMutableDataRef data = NULL;
      CFSocketError retval;
      CFIndex length;
      uint8_t bytes[4];
      if (NULL == signature) {
          retval = CFSocketUnregister(nameServerSignature, timeout, name);
      } else {
          __CFSocketValidateSignature(signature, &validatedSignature, 0);
          if (NULL == validatedSignature.address || 0 > validatedSignature.protocolFamily || 255 < validatedSignature.protocolFamily || 0 > validatedSignature.socketType || 255 < validatedSignature.socketType || 0 > validatedSignature.protocol || 255 < validatedSignature.protocol || 0 >= (length = CFDataGetLength(validatedSignature.address)) || 255 < length) {
              retval = kCFSocketError;
          } else {
              data = CFDataCreateMutable(kCFAllocatorSystemDefault, sizeof(bytes) + length);
              bytes[0] = validatedSignature.protocolFamily;
              bytes[1] = validatedSignature.socketType;
              bytes[2] = validatedSignature.protocol;
              bytes[3] = length;
              CFDataAppendBytes(data, bytes, sizeof(bytes));
              CFDataAppendBytes(data, CFDataGetBytePtr(validatedSignature.address), length);
              retval = CFSocketRegisterValue(nameServerSignature, timeout, name, data);
              CFRelease(data);
          }
          CFRelease(validatedSignature.address);
      }
      return retval;
  }
  
  CFSocketError CFSocketCopyRegisteredSocketSignature(const CFSocketSignature *nameServerSignature, CFTimeInterval timeout, CFStringRef name, CFSocketSignature *signature, CFDataRef *nameServerAddress) {
      CFDataRef data = NULL;
      CFSocketSignature returnedSignature;
      const uint8_t *ptr = NULL, *aptr = NULL;
      uint8_t *mptr;
      CFIndex length = 0;
      CFDataRef serverAddress = NULL;
      CFSocketError retval = CFSocketCopyRegisteredValue(nameServerSignature, timeout, name, (CFPropertyListRef *)&data, &serverAddress);
      if (NULL == data || CFGetTypeID(data) != CFDataGetTypeID() || NULL == (ptr = CFDataGetBytePtr(data)) || (length = CFDataGetLength(data)) < 4) retval = kCFSocketError;
      if (kCFSocketSuccess == retval && NULL != signature) {
          returnedSignature.protocolFamily = (SInt32)*ptr++;
          returnedSignature.socketType = (SInt32)*ptr++;
          returnedSignature.protocol = (SInt32)*ptr++;
          ptr++;
          returnedSignature.address = CFDataCreate(kCFAllocatorSystemDefault, ptr, length - 4);
          __CFSocketValidateSignature(&returnedSignature, signature, 0);
          CFRelease(returnedSignature.address);
          ptr = CFDataGetBytePtr(signature->address);
          if (CFDataGetLength(signature->address) >= (int)sizeof(struct sockaddr_in) && AF_INET == ((struct sockaddr *)ptr)->sa_family && NULL != serverAddress && CFDataGetLength(serverAddress) >= (int)sizeof(struct sockaddr_in) && NULL != (aptr = CFDataGetBytePtr(serverAddress)) && AF_INET == ((struct sockaddr *)aptr)->sa_family) {
              CFMutableDataRef address = CFDataCreateMutableCopy(kCFAllocatorSystemDefault, CFDataGetLength(signature->address), signature->address);
              mptr = CFDataGetMutableBytePtr(address);
              ((struct sockaddr_in *)mptr)->sin_addr = ((struct sockaddr_in *)aptr)->sin_addr;
              CFRelease(signature->address);
              signature->address = address;
          }
          if (NULL != nameServerAddress) *nameServerAddress = serverAddress ? (CFDataRef)CFRetain(serverAddress) : NULL;
      }
      if (NULL != data) CFRelease(data);
      if (NULL != serverAddress) CFRelease(serverAddress);
      return retval;
  }
  
  CFSocketError CFSocketUnregister(const CFSocketSignature *nameServerSignature, CFTimeInterval timeout, CFStringRef name) {
      return CFSocketRegisterValue(nameServerSignature, timeout, name, NULL);
  }
  
  CF_EXPORT void CFSocketSetDefaultNameRegistryPortNumber(uint16_t port) {
      __CFSocketDefaultNameRegistryPortNumber = port;
  }
  
  CF_EXPORT uint16_t CFSocketGetDefaultNameRegistryPortNumber(void) {
      return __CFSocketDefaultNameRegistryPortNumber;
  }
  
  