comparison src/mac.c @ 79509:e4c75e9b905b

(cfsockets_for_select) [MAC_OSX && SELECT_USE_CFSOCKET]: New variable. (mac_try_close_socket) [MAC_OSX]: New function. [MAC_OSX] (sys_select) [SELECT_USE_CFSOCKET]: Update cfsockets_for_select. Replace invalid CFRunLoop source.
author YAMAMOTO Mitsuharu <mituharu@math.s.chiba-u.ac.jp>
date Fri, 30 Nov 2007 08:19:36 +0000
parents ccca2e6b8cd9
children fc2bcd2a8aad ec0ef12211d9
comparison
equal deleted inserted replaced
79508:226de5ee19d3 79509:e4c75e9b905b
5007 5007
5008 #define SELECT_POLLING_PERIOD_USEC 100000 5008 #define SELECT_POLLING_PERIOD_USEC 100000
5009 #if SELECT_USE_CFSOCKET 5009 #if SELECT_USE_CFSOCKET
5010 #define SELECT_TIMEOUT_THRESHOLD_RUNLOOP 0.2 5010 #define SELECT_TIMEOUT_THRESHOLD_RUNLOOP 0.2
5011 5011
5012 /* Dictionary of file descriptors vs CFSocketRef's allocated in
5013 sys_select. */
5014 static CFMutableDictionaryRef cfsockets_for_select;
5015
5012 static void 5016 static void
5013 socket_callback (s, type, address, data, info) 5017 socket_callback (s, type, address, data, info)
5014 CFSocketRef s; 5018 CFSocketRef s;
5015 CFSocketCallBackType type; 5019 CFSocketCallBackType type;
5016 CFDataRef address; 5020 CFDataRef address;
5076 } 5080 }
5077 else 5081 else
5078 return 0; 5082 return 0;
5079 } 5083 }
5080 5084
5085 /* Clean up the CFSocket associated with the file descriptor FD in
5086 case the same descriptor is used in other threads later. If no
5087 CFSocket is associated with FD, then return 0 without closing FD.
5088 Otherwise, return 1 with closing FD. */
5089
5090 int
5091 mac_try_close_socket (fd)
5092 int fd;
5093 {
5094 #if SELECT_USE_CFSOCKET
5095 if (cfsockets_for_select)
5096 {
5097 void *key = (void *) fd;
5098 CFSocketRef socket =
5099 (CFSocketRef) CFDictionaryGetValue (cfsockets_for_select, key);
5100
5101 if (socket)
5102 {
5103 #if MAC_OS_X_VERSION_MAX_ALLOWED >= 1020
5104 CFOptionFlags flags = CFSocketGetSocketFlags (socket);
5105
5106 if (!(flags & kCFSocketCloseOnInvalidate))
5107 CFSocketSetSocketFlags (socket, flags | kCFSocketCloseOnInvalidate);
5108 #endif
5109 BLOCK_INPUT;
5110 CFSocketInvalidate (socket);
5111 CFDictionaryRemoveValue (cfsockets_for_select, key);
5112 UNBLOCK_INPUT;
5113
5114 return 1;
5115 }
5116 }
5117 #endif
5118
5119 return 0;
5120 }
5121
5081 int 5122 int
5082 sys_select (nfds, rfds, wfds, efds, timeout) 5123 sys_select (nfds, rfds, wfds, efds, timeout)
5083 int nfds; 5124 int nfds;
5084 SELECT_TYPE *rfds, *wfds, *efds; 5125 SELECT_TYPE *rfds, *wfds, *efds;
5085 EMACS_TIME *timeout; 5126 EMACS_TIME *timeout;
5154 if (sources == NULL) 5195 if (sources == NULL)
5155 sources = 5196 sources =
5156 CFDictionaryCreateMutable (NULL, 0, NULL, 5197 CFDictionaryCreateMutable (NULL, 0, NULL,
5157 &kCFTypeDictionaryValueCallBacks); 5198 &kCFTypeDictionaryValueCallBacks);
5158 5199
5200 if (cfsockets_for_select == NULL)
5201 cfsockets_for_select =
5202 CFDictionaryCreateMutable (NULL, 0, NULL,
5203 &kCFTypeDictionaryValueCallBacks);
5204
5159 for (minfd = 1; ; minfd++) /* nfds-1 works as a sentinel. */ 5205 for (minfd = 1; ; minfd++) /* nfds-1 works as a sentinel. */
5160 if (FD_ISSET (minfd, rfds) || (wfds && FD_ISSET (minfd, wfds))) 5206 if (FD_ISSET (minfd, rfds) || (wfds && FD_ISSET (minfd, wfds)))
5161 break; 5207 break;
5162 5208
5163 for (fd = minfd; fd < nfds; fd++) 5209 for (fd = minfd; fd < nfds; fd++)
5165 { 5211 {
5166 void *key = (void *) fd; 5212 void *key = (void *) fd;
5167 CFRunLoopSourceRef source = 5213 CFRunLoopSourceRef source =
5168 (CFRunLoopSourceRef) CFDictionaryGetValue (sources, key); 5214 (CFRunLoopSourceRef) CFDictionaryGetValue (sources, key);
5169 5215
5170 if (source == NULL) 5216 if (source == NULL || !CFRunLoopSourceIsValid (source))
5171 { 5217 {
5172 CFSocketRef socket = 5218 CFSocketRef socket =
5173 CFSocketCreateWithNative (NULL, fd, 5219 CFSocketCreateWithNative (NULL, fd,
5174 (kCFSocketReadCallBack 5220 (kCFSocketReadCallBack
5175 | kCFSocketConnectCallBack), 5221 | kCFSocketConnectCallBack),
5176 socket_callback, &context); 5222 socket_callback, &context);
5177 5223
5178 if (socket == NULL) 5224 if (socket == NULL)
5179 continue; 5225 continue;
5226 CFDictionarySetValue (cfsockets_for_select, key, socket);
5180 source = CFSocketCreateRunLoopSource (NULL, socket, 0); 5227 source = CFSocketCreateRunLoopSource (NULL, socket, 0);
5181 CFRelease (socket); 5228 CFRelease (socket);
5182 if (source == NULL) 5229 if (source == NULL)
5183 continue; 5230 continue;
5184 CFDictionaryAddValue (sources, key, source); 5231 CFDictionarySetValue (sources, key, source);
5185 CFRelease (source); 5232 CFRelease (source);
5186 } 5233 }
5187 CFRunLoopAddSource (runloop, source, kCFRunLoopDefaultMode); 5234 CFRunLoopAddSource (runloop, source, kCFRunLoopDefaultMode);
5188 } 5235 }
5189 5236