private void addAndStartSubscriberThread(SoftwareClockSubscriber sub) { lock (lockObj) { Thread thread = new Thread(new ParameterizedThreadStart(subscriberThreadProc)); subscriberThreads.Add(sub, thread); runningSubscriberThreads++; thread.Start(new SubscriberThreadParameters(sub, subscriberPollingPeriods_ms[sub], subscriberPritorities[sub])); } }
private void subscriberThreadProc(object param) { try { if (!(param is SubscriberThreadParameters)) { throw new SoftwareClockProviderException("Passed wrong parameter type to subscriberThreadProc"); } SubscriberThreadParameters parameters = (SubscriberThreadParameters)param; SoftwareClockSubscriber subscriber = parameters.subscriber; int minPollingPeriod_ms = parameters.minPollTime_ms; int priority = parameters.priority; uint lastPoll = elapsedTime_ms; bool keepGoing = true; while (keepGoing) { lock (synchronizationObject) { Monitor.Wait(synchronizationObject); } uint thisPoll = elapsedTime_ms; if ((thisPoll - lastPoll) < minPollingPeriod_ms) { continue; } lastPoll = thisPoll; try { keepGoing = subscriber.reachedTime(thisPoll, priority); } catch (Exception e) { if (!subscriber.handleExceptionOnClockThread(e)) { throw; } } } } finally { lock (lockObj) runningSubscriberThreads--; } }
/// <summary> /// Add a subscriber to this clock provider. /// /// This function may be called even after the software clock has been started with a Start() call. /// /// Priority is an optional integer parameter that gets passed to the subscriber in addition to the time /// Subscriber may use this to decide among several clock sources. /// /// All calls to the subscriber's reachTime and finish() methods are guaranteed to occur on one dedicated thread. /// /// Note: if a subscriber subscriber to multiple providers, calls from different providers are NOT /// guaranteed to be on the same thread. /// </summary> /// <param name="sub"></param> /// <param name="minimumPollingPerios_ms"></param> public void addSubscriber(SoftwareClockSubscriber sub, int minimumPollingPerios_ms = 0, int priority = 0) { lock (lockObj) { subscribers.Add(sub); subscriberPollingPeriods_ms.Add(sub, minimumPollingPerios_ms); subscriberPritorities.Add(sub, priority); if (threadsRunning) { addAndStartSubscriberThread(sub); } } }
/// <summary> /// Add a subscriber to this clock provider. /// /// This function may be called even after the software clock has been started with a Start() call. /// /// Priority is an optional integer parameter that gets passed to the subscriber in addition to the time /// Subscriber may use this to decide among several clock sources. /// /// All calls to the subscriber's reachTime and finish() methods are guaranteed to occur on one dedicated thread. /// /// Note: if a subscriber subscriber to multiple providers, calls from different providers are NOT /// guaranteed to be on the same thread. /// </summary> /// <param name="sub"></param> /// <param name="minimumPollingPerios_ms"></param> public void addSubscriber(SoftwareClockSubscriber sub, int minimumPollingPerios_ms = 0, int priority=0) { lock (lockObj) { subscribers.Add(sub); subscriberPollingPeriods_ms.Add(sub, minimumPollingPerios_ms); subscriberPritorities.Add(sub, priority); if (threadsRunning) { addAndStartSubscriberThread(sub); } } }
public SubscriberThreadParameters(SoftwareClockSubscriber sub, int minPollTime_ms, int priority) { this.subscriber = sub; this.minPollTime_ms = minPollTime_ms; this.priority = priority; }