comparison mac/dw.m @ 694:130ca42c4ae3

Reimplementation of dw_main_iteration and dw_main_sleep that actually work. This fixes deadlocks in the control center application, but seems to be a bit slow.
author bsmith@81767d24-ef19-dc11-ae90-00e081727c95
date Thu, 10 Mar 2011 18:58:05 +0000
parents 2f21ee9d7c7b
children 3b17111499bf
comparison
equal deleted inserted replaced
693:2f21ee9d7c7b 694:130ca42c4ae3
225 @implementation DWTimerHandler 225 @implementation DWTimerHandler
226 -(void)runTimer:(id)sender { _event_handler(sender, nil, 0); } 226 -(void)runTimer:(id)sender { _event_handler(sender, nil, 0); }
227 @end 227 @end
228 228
229 NSApplication *DWApp; 229 NSApplication *DWApp;
230 NSRunLoop *DWRunLoop;
231 NSMenu *DWMainMenu; 230 NSMenu *DWMainMenu;
232 DWTimerHandler *DWHandler; 231 DWTimerHandler *DWHandler;
233 #if !defined(GARBAGE_COLLECT) 232 #if !defined(GARBAGE_COLLECT)
234 NSAutoreleasePool *pool; 233 NSAutoreleasePool *pool;
235 #endif 234 #endif
1665 */ 1664 */
1666 int API dw_init(int newthread, int argc, char *argv[]) 1665 int API dw_init(int newthread, int argc, char *argv[])
1667 { 1666 {
1668 /* Create the application object */ 1667 /* Create the application object */
1669 DWApp = [NSApplication sharedApplication]; 1668 DWApp = [NSApplication sharedApplication];
1670 /* Create a run loop for doing manual loops */
1671 DWRunLoop = [NSRunLoop alloc];
1672 /* Create object for handling timers */ 1669 /* Create object for handling timers */
1673 DWHandler = [[DWTimerHandler alloc] init]; 1670 DWHandler = [[DWTimerHandler alloc] init];
1674 /* If we aren't using garbage collection we need autorelease pools */ 1671 /* If we aren't using garbage collection we need autorelease pools */
1675 #if !defined(GARBAGE_COLLECT) 1672 #if !defined(GARBAGE_COLLECT)
1676 pool = [[NSAutoreleasePool alloc] init]; 1673 pool = [[NSAutoreleasePool alloc] init];
1707 * Parameters: 1704 * Parameters:
1708 * milliseconds: Number of milliseconds to run the loop for. 1705 * milliseconds: Number of milliseconds to run the loop for.
1709 */ 1706 */
1710 void API dw_main_sleep(int milliseconds) 1707 void API dw_main_sleep(int milliseconds)
1711 { 1708 {
1712 double seconds = (double)milliseconds/1000.0; 1709 struct timeval tv, start;
1713 NSDate *time = [[NSDate alloc] initWithTimeIntervalSinceNow:seconds]; 1710 DWTID curr = pthread_self();
1714 [DWRunLoop runUntilDate:time]; 1711
1715 [time release]; 1712 gettimeofday(&start, NULL);
1713
1714 if(DWThread == (DWTID)-1 || DWThread == curr)
1715 {
1716 DWTID orig = DWThread;
1717
1718 gettimeofday(&tv, NULL);
1719
1720 dw_mutex_lock(DWRunMutex);
1721 while(((tv.tv_sec - start.tv_sec)*1000) + ((tv.tv_usec - start.tv_usec)/1000) <= milliseconds)
1722 {
1723 if(orig == (DWTID)-1)
1724 {
1725 DWThread = curr;
1726 }
1727 dw_main_iteration();
1728 if(orig == (DWTID)-1)
1729 {
1730 DWThread = orig;
1731 }
1732 gettimeofday(&tv, NULL);
1733 }
1734 dw_mutex_unlock(DWRunMutex);
1735 }
1736 else
1737 usleep(milliseconds * 1000);
1716 } 1738 }
1717 1739
1718 /* 1740 /*
1719 * Processes a single message iteration and returns. 1741 * Processes a single message iteration and returns.
1720 */ 1742 */
1721 void API dw_main_iteration(void) 1743 void API dw_main_iteration(void)
1722 { 1744 {
1723 [DWRunLoop limitDateForMode:NSDefaultRunLoopMode]; 1745 NSDate *distant_future = [NSDate distantFuture];
1746 NSEvent *event = [DWApp nextEventMatchingMask:NSAnyEventMask
1747 untilDate:distant_future
1748 inMode:NSDefaultRunLoopMode
1749 dequeue:YES];
1750 if(event)
1751 {
1752 [DWApp sendEvent:event];
1753 }
1724 } 1754 }
1725 1755
1726 /* 1756 /*
1727 * Cleanly terminates a DW session, should be signal handler safe. 1757 * Cleanly terminates a DW session, should be signal handler safe.
1728 * Parameters: 1758 * Parameters: