📄 basicdaemon.java
字号:
return; } SanityManager.DEBUG(DaemonService.DaemonTrace, "running"); } // infinite loop of rest and work while(true) { if (stopRequested()) break; // if someone wake me up, only service the urgent requests. // if I wake up by my regular schedule, service all clients boolean urgentOnly = rest(); if (stopRequested()) break; if (!inPause()) work(urgentOnly); } synchronized(this) { running = false; stopped = true; } contextMgr.cleanupOnError(StandardException.normalClose()); contextService.resetCurrentContextManager(contextMgr); } /* * Daemon Service method */ /* * pause the daemon. Wait till it is no running before it returns */ public void pause() { if (SanityManager.DEBUG) { if (SanityManager.DEBUG_ON(DaemonService.DaemonTrace)) SanityManager.DEBUG(DaemonService.DaemonTrace, "pausing daemon"); } synchronized(this) { inPause = true; while(running) { if (SanityManager.DEBUG) { if (SanityManager.DEBUG_ON(DaemonService.DaemonTrace)) SanityManager.DEBUG(DaemonService.DaemonTrace, "waiting for daemon run to finish"); } try { wait(); } catch (InterruptedException ie) { // someone interrrupt us, done running } } } if (SanityManager.DEBUG) { if (SanityManager.DEBUG_ON(DaemonService.DaemonTrace)) SanityManager.DEBUG(DaemonService.DaemonTrace, "daemon paused"); } } public void resume() { synchronized(this) { inPause = false; } if (SanityManager.DEBUG) { if (SanityManager.DEBUG_ON(DaemonService.DaemonTrace)) SanityManager.DEBUG(DaemonService.DaemonTrace, "daemon resumed"); } } /** Finish what we are doing and at the next convenient moment, get rid of the thread and make the daemon object goes away if possible. remember we are calling from another thread */ public void stop() { if (stopped) // already stopped return; synchronized(this) { stopRequested = true; notifyAll(); // get sleeper to wake up and stop ASAP } pause(); // finish doing what we are doing first } /* **Wait until the work in the high priority queue is done. **Note: Used by tests only to make sure all the work **assigned to the daemon is completed. **/ public void waitUntilQueueIsEmpty() { while(true){ synchronized(this) { boolean noSubscriptionRequests = true; for (int urgentServiced = 0; urgentServiced < subscription.size(); urgentServiced++) { ServiceRecord clientRecord = (ServiceRecord)subscription.elementAt(urgentServiced); if (clientRecord != null && clientRecord.needService()) { noSubscriptionRequests = false; break; } } if (highPQ.isEmpty() && noSubscriptionRequests &&!running){ return; }else{ notifyAll(); //wake up the the daemon thread //wait for the raw store daemon to wakeus up //when it finihes work. try{ wait(); }catch (InterruptedException ie) { // someone interrupt us, see what's going on } } } } } private synchronized boolean stopRequested() { return stopRequested; } private synchronized boolean inPause() { return inPause; } /* * BasicDaemon method */ protected synchronized void wakeUp() { if (!awakened) { awakened = true; // I am being awakened for urgent work. if (waiting) { notifyAll(); } } } /** Returns true if awakened by some notification, false if wake up by timer */ private boolean rest() { if (SanityManager.DEBUG) { if (SanityManager.DEBUG_ON(DaemonService.DaemonTrace)) SanityManager.DEBUG(DaemonService.DaemonTrace, "going back to rest"); } boolean urgentOnly; boolean checkWallClock = false; synchronized(this) { try { if (!awakened) { waiting = true; wait(DaemonService.TIMER_DELAY); waiting = false; } } catch (InterruptedException ie) { // someone interrupt us, see what's going on } nextService = 0; urgentOnly = awakened; if (urgentOnly) // check wall clock { // take a guess that each early request is services every 500ms. if (earlyWakeupCount++ > (DaemonService.TIMER_DELAY / 500)) { earlyWakeupCount = 0; checkWallClock = true; } } awakened = false; // reset this for next time } if (SanityManager.DEBUG) { if (SanityManager.DEBUG_ON(DaemonService.DaemonTrace)) SanityManager.DEBUG(DaemonService.DaemonTrace, urgentOnly ? "someone wakes me up" : "wakes up by myself"); } if (checkWallClock) { long currenttime = System.currentTimeMillis(); if ((currenttime - lastServiceTime) > DaemonService.TIMER_DELAY) { lastServiceTime = currenttime; urgentOnly = false; if (SanityManager.DEBUG) { if (SanityManager.DEBUG_ON(DaemonService.DaemonTrace)) SanityManager.DEBUG(DaemonService.DaemonTrace, "wall clock check says service all"); } } } return urgentOnly; } private void work(boolean urgentOnly) { if (SanityManager.DEBUG) { if (SanityManager.DEBUG_ON(DaemonService.DaemonTrace)) SanityManager.DEBUG(DaemonService.DaemonTrace, "going back to work"); } ServiceRecord work; // while I am working, all serviceNow requests that comes in now will // be taken care of when we get the next Assignment. int serviceCount = 0; int yieldFactor = 10; if (urgentOnly && (highPQ.size() > OPTIMAL_QUEUE_SIZE)) yieldFactor = 2; int yieldCount = OPTIMAL_QUEUE_SIZE / yieldFactor; for (work = nextAssignment(urgentOnly); work != null; work = nextAssignment(urgentOnly)) { if (SanityManager.DEBUG) { if (SanityManager.DEBUG_ON(DaemonService.DaemonTrace)) SanityManager.DEBUG(DaemonService.DaemonTrace, "servicing " + work); } synchronized(this) { if (inPause || stopRequested) break; // don't do anything more running = true; } // do work try { serviceClient(work); serviceCount++; } finally { // catch run time exceptions synchronized(this) { running = false; notifyAll(); if (inPause || stopRequested) break; // don't do anything more } } if (SanityManager.DEBUG) { if (SanityManager.DEBUG_ON(DaemonService.DaemonTrace)) SanityManager.DEBUG(DaemonService.DaemonTrace, "done " + work); } // ensure the subscribed clients get a look in once in a while // when the queues are large. if ((serviceCount % (OPTIMAL_QUEUE_SIZE / 2)) == 0) { nextService = 0; } if ((serviceCount % yieldCount) == 0) { yield(); } if (SanityManager.DEBUG) { if (SanityManager.DEBUG_ON(DaemonService.DaemonTrace)) SanityManager.DEBUG(DaemonService.DaemonTrace, "come back from yield"); } } } /* let everybody else run first */ private void yield() { Thread currentThread = Thread.currentThread(); int oldPriority = currentThread.getPriority(); if (oldPriority <= Thread.MIN_PRIORITY) { currentThread.yield(); } else { ModuleFactory mf = Monitor.getMonitor(); if (mf != null) mf.setThreadPriority(Thread.MIN_PRIORITY); currentThread.yield(); if (mf != null) mf.setThreadPriority(oldPriority); } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -