static void __CFWindowsMessageQueuePerform(void *info) { CFWindowsMessageQueueRef wmq = (CFWindowsMessageQueueRef)info; MSG msg; __CFWindowsMessageQueueLock(wmq); if (!__CFWindowsMessageQueueIsValid(wmq)) { __CFWindowsMessageQueueUnlock(wmq); return; } __CFWindowsMessageQueueUnlock(wmq); if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE | PM_NOYIELD)) { TranslateMessage(&msg); DispatchMessage(&msg); } }
static void __CFWindowsMessageQueueSchedule(void *info, CFRunLoopRef rl, CFStringRef mode) { CFWindowsMessageQueueRef wmq = (CFWindowsMessageQueueRef)info; __CFWindowsMessageQueueLock(wmq); if (__CFWindowsMessageQueueIsValid(wmq)) { uint32_t mask; CFArrayAppendValue(wmq->_runLoops, rl); mask = __CFRunLoopGetWindowsMessageQueueMask(rl, mode); mask |= wmq->_mask; __CFRunLoopSetWindowsMessageQueueMask(rl, mask, mode); } __CFWindowsMessageQueueUnlock(wmq); }
static void __CFWindowsMessageQueueCancel(void *info, CFRunLoopRef rl, CFStringRef mode) { CFWindowsMessageQueueRef wmq = info; __CFWindowsMessageQueueLock(wmq); #warning CF: should fix up run loop modes mask here, if not done #warning CF: previously by the invalidation, where it should also #warning CF: be done if (NULL != wmq->_runLoops) { SInt32 idx = CFArrayGetFirstIndexOfValue(wmq->_runLoops, CFRangeMake(0, CFArrayGetCount(wmq->_runLoops)), rl); if (0 <= idx) CFArrayRemoveValueAtIndex(wmq->_runLoops, idx); } __CFWindowsMessageQueueUnlock(wmq); }
CFStringRef __CFWindowsMessageQueueCopyDescription(CFTypeRef cf) { #warning CF: this and many other CopyDescription functions are probably #warning CF: broken, in that some of these fields being printed out can #warning CF: be NULL, when the object is in the invalid state CFWindowsMessageQueueRef wmq = (CFWindowsMessageQueueRef)cf; CFMutableStringRef result; result = CFStringCreateMutable(CFGetAllocator(wmq), 0); __CFWindowsMessageQueueLock(wmq); #warning CF: here, and probably everywhere with a per-instance lock, #warning CF: the locked state will always be true because we lock, #warning CF: and you cannot call description if the object is locked; #warning CF: probably should not lock description, and call it unsafe CFStringAppendFormat(result, NULL, CFSTR("<CFWindowsMessageQueue 0x%x [0x%x]>{locked = %s, valid = %s, mask = 0x%x,\n run loops = %@}"), (UInt32)cf, (UInt32)CFGetAllocator(wmq), (wmq->_lock ? "Yes" : "No"), (__CFWindowsMessageQueueIsValid(wmq) ? "Yes" : "No"), (UInt32)wmq->_mask, wmq->_runLoops); __CFWindowsMessageQueueUnlock(wmq); return result; }
static CFStringRef __CFWindowsMessageQueueCopyDescription(CFTypeRef cf) { /* Some commentary, possibly as out of date as much of the rest of the file was #warning CF: this and many other CopyDescription functions are probably #warning CF: broken, in that some of these fields being printed out can #warning CF: be NULL, when the object is in the invalid state */ CFWindowsMessageQueueRef wmq = (CFWindowsMessageQueueRef)cf; CFMutableStringRef result; result = CFStringCreateMutable(CFGetAllocator(wmq), 0); __CFWindowsMessageQueueLock(wmq); /* More commentary, which we don't really need to see with every build #warning CF: here, and probably everywhere with a per-instance lock, #warning CF: the locked state will always be true because we lock, #warning CF: and you cannot call description if the object is locked; #warning CF: probably should not lock description, and call it unsafe */ CFStringAppendFormat(result, NULL, CFSTR("<CFWindowsMessageQueue %p [%p]>{locked = %s, valid = %s, mask = 0x%x,\n run loops = %@}"), cf, CFGetAllocator(wmq), (wmq->_lock/*.LockCount*/ ? "Yes" : "No"), (__CFWindowsMessageQueueIsValid(wmq) ? "Yes" : "No"), (UInt32)wmq->_mask, wmq->_runLoops); __CFWindowsMessageQueueUnlock(wmq); return result; }
void CFWindowsMessageQueueInvalidate(CFWindowsMessageQueueRef wmq) { __CFGenericValidateType(wmq, __kCFWindowsMessageQueueTypeID); CFRetain(wmq); __CFWindowsMessageQueueLock(wmq); if (__CFWindowsMessageQueueIsValid(wmq)) { SInt32 idx; __CFWindowsMessageQueueUnsetValid(wmq); for (idx = CFArrayGetCount(wmq->_runLoops); idx--;) { CFRunLoopWakeUp((CFRunLoopRef)CFArrayGetValueAtIndex(wmq->_runLoops, idx)); } CFRelease(wmq->_runLoops); wmq->_runLoops = NULL; if (NULL != wmq->_source) { CFRunLoopSourceInvalidate(wmq->_source); CFRelease(wmq->_source); wmq->_source = NULL; } } __CFWindowsMessageQueueUnlock(wmq); CFRelease(wmq); }
CFRunLoopSourceRef CFWindowsMessageQueueCreateRunLoopSource(CFAllocatorRef allocator, CFWindowsMessageQueueRef wmq, CFIndex order) { CFRunLoopSourceRef result = NULL; __CFWindowsMessageQueueLock(wmq); if (NULL == wmq->_source) { CFRunLoopSourceContext context; context.version = 0; context.info = (void *)wmq; context.retain = CFRetain; context.release = CFRelease; context.copyDescription = __CFWindowsMessageQueueCopyDescription; context.equal = __CFWindowsMessageQueueEqual; context.hash = __CFWindowsMessageQueueHash; context.schedule = __CFWindowsMessageQueueSchedule; context.cancel = __CFWindowsMessageQueueCancel; context.perform = __CFWindowsMessageQueuePerform; wmq->_source = CFRunLoopSourceCreate(allocator, order, &context); } CFRetain(wmq->_source); /* This retain is for the receiver */ result = wmq->_source; __CFWindowsMessageQueueUnlock(wmq); return result; }