coroutinemanager.java
来自「java jdk 1.4的源码」· Java 代码 · 共 382 行 · 第 1/2 页
JAVA
382 行
/** Internal field used to confirm that the coroutine now waking up is * in fact the one we intended to resume. Some such selection mechanism * is needed when more that two coroutines are operating within the same * group. */ int m_nextCoroutine=NOBODY; /** <p>Each coroutine in the set managed by a single * CoroutineManager is identified by a small positive integer. This * brings up the question of how to manage those integers to avoid * reuse... since if two coroutines use the same ID number, resuming * that ID could resume either. I can see arguments for either * allowing applications to select their own numbers (they may want * to declare mnemonics via manefest constants) or generating * numbers on demand. This routine's intended to support both * approaches.</p> * * <p>%REVIEW% We could use an object as the identifier. Not sure * it's a net gain, though it would allow the thread to be its own * ID. Ponder.</p> * * @param coroutineID: If >=0, requests that we reserve this number. * If <0, requests that we find, reserve, and return an available ID * number. * * @return If >=0, the ID number to be used by this coroutine. If <0, * an error occurred -- the ID requested was already in use, or we * couldn't assign one without going over the "unreasonable value" mark * */ public synchronized int co_joinCoroutineSet(int coroutineID) { if(coroutineID>=0) { if(coroutineID>=m_unreasonableId || m_activeIDs.get(coroutineID)) return -1; } else { // What I want is "Find first clear bit". That doesn't exist. // JDK1.2 added "find last set bit", but that doesn't help now. coroutineID=0; while(coroutineID<m_unreasonableId) { if(m_activeIDs.get(coroutineID)) ++coroutineID; else break; } if(coroutineID>=m_unreasonableId) return -1; } m_activeIDs.set(coroutineID); return coroutineID; } /** In the standard coroutine architecture, coroutines are * identified by their method names and are launched and run up to * their first yield by simply resuming them; its's presumed that * this recognizes the not-already-running case and does the right * thing. We seem to need a way to achieve that same threadsafe * run-up... eg, start the coroutine with a wait. * * %TBD% whether this makes any sense... * * @param thisCoroutine the identifier of this coroutine, so we can * recognize when we are being resumed. * @exception java.lang.NoSuchMethodException if thisCoroutine isn't * a registered member of this group. %REVIEW% whether this is the * best choice. * */ public synchronized Object co_entry_pause(int thisCoroutine) throws java.lang.NoSuchMethodException { if(!m_activeIDs.get(thisCoroutine)) throw new java.lang.NoSuchMethodException(); while(m_nextCoroutine != thisCoroutine) { try { wait(); } catch(java.lang.InterruptedException e) { // %TBD% -- Declare? Encapsulate? Ignore? Or // dance widdershins about the instruction cache? } } return m_yield; } /** Transfer control to another coroutine which has already been started and * is waiting on this CoroutineManager. We won't return from this call * until that routine has relinquished control. * * %TBD% What should we do if toCoroutine isn't registered? Exception? * * @param arg_object A value to be passed to the other coroutine. * @param thisCoroutine Integer identifier for this coroutine. This is the * ID we watch for to see if we're the ones being resumed. * @param toCoroutine. Integer identifier for the coroutine we wish to * invoke. * @exception java.lang.NoSuchMethodException if toCoroutine isn't a * registered member of this group. %REVIEW% whether this is the best choice. * */ public synchronized Object co_resume(Object arg_object,int thisCoroutine,int toCoroutine) throws java.lang.NoSuchMethodException { if(!m_activeIDs.get(toCoroutine)) throw new java.lang.NoSuchMethodException(XSLMessages.createMessage(XSLTErrorResources.ER_COROUTINE_NOT_AVAIL, new Object[]{Integer.toString(toCoroutine)})); //"Coroutine not available, id="+toCoroutine); // We expect these values to be overwritten during the notify()/wait() // periods, as other coroutines in this set get their opportunity to run. m_yield=arg_object; m_nextCoroutine=toCoroutine; notify(); while(m_nextCoroutine != thisCoroutine || m_nextCoroutine==ANYBODY || m_nextCoroutine==NOBODY) { try { // System.out.println("waiting..."); wait(); } catch(java.lang.InterruptedException e) { // %TBD% -- Declare? Encapsulate? Ignore? Or // dance deasil about the program counter? } } if(m_nextCoroutine==NOBODY) { // Pass it along co_exit(thisCoroutine); // And inform this coroutine that its partners are Going Away // %REVIEW% Should this throw/return something more useful? throw new java.lang.NoSuchMethodException(XSLMessages.createMessage(XSLTErrorResources.ER_COROUTINE_CO_EXIT, null)); //"CoroutineManager recieved co_exit() request"); } return m_yield; } /** Terminate this entire set of coroutines. The others will be * deregistered and have exceptions thrown at them. Note that this * is intended as a panic-shutdown operation; under normal * circumstances a coroutine should always end with co_exit_to() in * order to politely inform at least one of its partners that it is * going away. * * %TBD% This may need significantly more work. * * %TBD% Should this just be co_exit_to(,,CoroutineManager.PANIC)? * * @param thisCoroutine Integer identifier for the coroutine requesting exit. * */ public synchronized void co_exit(int thisCoroutine) { m_activeIDs.clear(thisCoroutine); m_nextCoroutine=NOBODY; // %REVIEW% notify(); } /** Make the ID available for reuse and terminate this coroutine, * transferring control to the specified coroutine. Note that this * returns immediately rather than waiting for any further coroutine * traffic, so the thread can proceed with other shutdown activities. * * @param arg_object A value to be passed to the other coroutine. * @param thisCoroutine Integer identifier for the coroutine leaving the set. * @param toCoroutine. Integer identifier for the coroutine we wish to * invoke. * @exception java.lang.NoSuchMethodException if toCoroutine isn't a * registered member of this group. %REVIEW% whether this is the best choice. * */ public synchronized void co_exit_to(Object arg_object,int thisCoroutine,int toCoroutine) throws java.lang.NoSuchMethodException { if(!m_activeIDs.get(toCoroutine)) throw new java.lang.NoSuchMethodException(XSLMessages.createMessage(XSLTErrorResources.ER_COROUTINE_NOT_AVAIL, new Object[]{Integer.toString(toCoroutine)})); //"Coroutine not available, id="+toCoroutine); // We expect these values to be overwritten during the notify()/wait() // periods, as other coroutines in this set get their opportunity to run. m_yield=arg_object; m_nextCoroutine=toCoroutine; m_activeIDs.clear(thisCoroutine); notify(); }}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?