StdScheduler::Added is not necessarily called from the thread the

procedure is meant to be run on, so introduce yet another StdScheduler
extra method StartOnCurrentThread which on Mac OS X does the actual run
loop registration stuff and needs to be called from the actual thread
the scheduler is supposed to run on

StdSchedulerMac: Remove SCHAdditions objects again
heavy-resources
Martin Plicht 2014-01-31 08:05:43 +01:00
parent c9521e2c3c
commit c3dd3a08ce
6 changed files with 58 additions and 21 deletions

View File

@ -149,6 +149,7 @@
#ifdef USE_COCOA
- (void) delayedRun:(id)sender
{
Application.StartOnCurrentThread();
running = YES;
//while (!Application.fQuitMsgReceived)
// Application.ScheduleProcs();

View File

@ -269,6 +269,7 @@ void *StdSchedulerThread::_ThreadFunc(void *pPar)
unsigned int StdSchedulerThread::ThreadFunc()
{
StartOnCurrentThread();
// Keep calling Execute until someone gets fed up and calls StopThread()
while (fRunThreadRun)
ScheduleProcs(1000);

View File

@ -238,9 +238,13 @@ public:
void Add(StdSchedulerProc *pProc);
void Remove(StdSchedulerProc *pProc);
// extra events for above Add/Remove methods
void Added(StdSchedulerProc *pProc);
void Removing(StdSchedulerProc *pProc);
// called by StdSchedulerProcs when something important about their configuration changed
void Changed(StdSchedulerProc *pProc);
// needs to be called on thread tasks for this scheduler are meant to be run on
void StartOnCurrentThread();
virtual bool ScheduleProcs(int iTimeout = -1);
void UnBlock();

View File

@ -41,11 +41,13 @@ using namespace std;
{
NSMutableDictionary* procAdditions;
}
+ (SCHAdditions*) requestAdditionsForScheduler:(StdScheduler*) scheduler;
- (id) initWithScheduler:(StdScheduler*) scheduler;
- (SCHAddition*) additionForProc:(StdSchedulerProc*) proc;
- (SCHAddition*) assignAdditionForProc:(StdSchedulerProc*) proc;
+ (SCHAdditions*) requestAdditionForScheduler:(StdScheduler*) scheduler;
- (void) changed:(SCHAddition*)addition;
- (BOOL) removeAdditionForProc:(StdSchedulerProc*) proc;
- (void) start;
@property(readonly) __weak NSRunLoop* runLoop;
@property(readonly) StdScheduler* scheduler;
@end
@ -54,12 +56,13 @@ using namespace std;
static NSMutableDictionary* additionsDictionary;
- (int) numberOfAdditions { return [additionsDictionary count]; }
- (id) initWithScheduler:(StdScheduler*) scheduler
{
if (self = [super init])
{
_scheduler = scheduler;
_runLoop = [NSRunLoop currentRunLoop];
procAdditions = [NSMutableDictionary new];
return self;
} else
@ -95,12 +98,40 @@ static NSMutableDictionary* additionsDictionary;
if (addition)
{
[procAdditions setObject:addition forKey:[NSNumber valueWithPointer:proc]];
if (_runLoop)
[addition registerAt:self];
return addition;
} else
return nullptr;
}
+ (SCHAdditions*) requestAdditionForScheduler:(StdScheduler *)scheduler
- (void) start
{
auto current = [NSRunLoop currentRunLoop];
if (current != [NSRunLoop mainRunLoop])
return; // oh well
_runLoop = current;
[procAdditions enumerateKeysAndObjectsUsingBlock:
^void (id key, SCHAddition* obj, BOOL* stop) { [obj registerAt:self]; }];
}
- (void) changed:(SCHAddition*)addition
{
[addition unregisterFrom:self];
if (_runLoop)
[addition registerAt:self];
}
+ (void) removeAdditions:(SCHAdditions*)additions
{
auto key = [NSNumber valueWithPointer:additions.scheduler];
@synchronized (additionsDictionary)
{
[additionsDictionary removeObjectForKey:key];
}
}
+ (SCHAdditions*) requestAdditionsForScheduler:(StdScheduler *)scheduler
{
static dispatch_once_t onceToken;
dispatch_once(&onceToken,
@ -132,6 +163,8 @@ static NSMutableDictionary* additionsDictionary;
}
- (bool) shouldExecuteProc
{
if (!proc)
return false;
auto s = schedulerAdditions;
return s && !s.scheduler->IsInManualLoop();
}
@ -145,9 +178,7 @@ static NSMutableDictionary* additionsDictionary;
}
- (void) changed
{
auto s = schedulerAdditions;
[self unregisterFrom:s];
[self registerAt:s];
[schedulerAdditions changed:self];
}
@end
@ -230,31 +261,26 @@ void callback (CFSocketRef s, CFSocketCallBackType type, CFDataRef address, cons
}
@end
void StdScheduler::StartOnCurrentThread()
{
[[SCHAdditions requestAdditionsForScheduler:this] start];
}
void StdScheduler::Added(StdSchedulerProc *pProc)
{
if ([NSRunLoop currentRunLoop] != [NSRunLoop mainRunLoop])
return; // scrap using that for other (network...) threads for now
auto x = [SCHAdditions requestAdditionForScheduler:this];
auto addition = [x assignAdditionForProc:pProc];
if (addition)
[addition registerAt:x];
[[SCHAdditions requestAdditionsForScheduler:this] assignAdditionForProc:pProc];
}
void StdScheduler::Removing(StdSchedulerProc *pProc)
{
if ([NSRunLoop currentRunLoop] != [NSRunLoop mainRunLoop])
return; // scrap using that for other (network...) threads for now
auto x = [SCHAdditions requestAdditionForScheduler:this];
auto x = [SCHAdditions requestAdditionsForScheduler:this];
[x removeAdditionForProc:pProc];
if ([x numberOfAdditions] == 0)
[SCHAdditions removeAdditions:x];
}
void StdScheduler::Changed(StdSchedulerProc* pProc)
{
if ([NSRunLoop currentRunLoop] != [NSRunLoop mainRunLoop])
return; // scrap using that for other (network...) threads for now
auto x = [SCHAdditions requestAdditionForScheduler:this];
auto addition = [x additionForProc:pProc];
if (addition)
[addition changed];
[[[SCHAdditions requestAdditionsForScheduler:this] additionForProc:pProc] changed];
}
#endif

View File

@ -236,6 +236,7 @@ void CStdMultimediaTimerProc::GetFDs(std::vector<struct pollfd> & checkfds)
void StdScheduler::Added(StdSchedulerProc *pProc) {}
void StdScheduler::Removing(StdSchedulerProc *pProc) {}
void StdScheduler::Changed(StdSchedulerProc* pProc) {}
void StdScheduler::StartOnCurrentThread() {}
#endif
void *StdThread::_ThreadFunc(void *pPar)

View File

@ -157,6 +157,10 @@ void StdScheduler::Changed(StdSchedulerProc* pProc)
{
}
void StdScheduler::StartOnCurrentThread()
{
}
bool CStdMultimediaTimerProc::CheckAndReset()
{
if (!Check()) return false;