diff options
| author | YAMAMOTO Mitsuharu | 2007-11-30 08:19:36 +0000 |
|---|---|---|
| committer | YAMAMOTO Mitsuharu | 2007-11-30 08:19:36 +0000 |
| commit | 6bfb1e350d82720d4a3f9a2ae6f69faf15198e9f (patch) | |
| tree | d627c313c4029e940a077f409428242504c7710d /src | |
| parent | 61a2fe01d87c381e2d33a1aa20a831435e630bf7 (diff) | |
| download | emacs-6bfb1e350d82720d4a3f9a2ae6f69faf15198e9f.tar.gz emacs-6bfb1e350d82720d4a3f9a2ae6f69faf15198e9f.zip | |
(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.
Diffstat (limited to 'src')
| -rw-r--r-- | src/mac.c | 51 |
1 files changed, 49 insertions, 2 deletions
| @@ -5009,6 +5009,10 @@ extern int noninteractive; | |||
| 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; |
| @@ -5078,6 +5082,43 @@ select_and_poll_event (nfds, rfds, wfds, efds, timeout) | |||
| 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; |
| @@ -5156,6 +5197,11 @@ sys_select (nfds, rfds, wfds, efds, timeout) | |||
| 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; |
| @@ -5167,7 +5213,7 @@ sys_select (nfds, rfds, wfds, efds, timeout) | |||
| 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, |
| @@ -5177,11 +5223,12 @@ sys_select (nfds, rfds, wfds, efds, timeout) | |||
| 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); |