internal virtual void HandleWorkCompletion() { WorkItem item = null; bool flag = false; lock (this._workItemQueue) { if (this._workItemQueue.Count >= 1) { item = (WorkItem)this._workItemQueue.Peek(); flag = true; item.SetSignaled(); } else { this._locked = false; } } if (flag) { if (item.IsAsync()) { this._asyncWorkEvent.Set(); } else { lock (item) { Monitor.Pulse(item); } } } }
// Token: 0x060057D6 RID: 22486 RVA: 0x00134A78 File Offset: 0x00132C78 internal virtual void HandleWorkCompletion() { WorkItem workItem = null; bool flag = false; Queue workItemQueue = this._workItemQueue; lock (workItemQueue) { if (this._workItemQueue.Count >= 1) { workItem = (WorkItem)this._workItemQueue.Peek(); flag = true; workItem.SetSignaled(); } else { this._locked = false; } } if (flag) { if (workItem.IsAsync()) { this._asyncWorkEvent.Set(); return; } WorkItem obj = workItem; lock (obj) { Monitor.Pulse(workItem); } } }
/* * This gets called at the end of work.Execute and from * HandleThreadExit() in the re-entrant scenario. * This is the point where we decide what to do next! */ internal virtual void HandleWorkCompletion() { // We should still have the lock held for the workItem that just completed Contract.Assert(_locked == true, "_locked==true"); // Now we check the queue to see if we need to release any one? WorkItem nextWork = null; bool bNotify = false; lock (_workItemQueue) { if (_workItemQueue.Count >= 1) { nextWork = (WorkItem)_workItemQueue.Peek(); bNotify = true; nextWork.SetSignaled(); } else { // We set locked to false only in the case there is no // next work to be done. // NOTE: this is the only place _locked in ever set to false! //DBGConsole.WriteLine(Thread.CurrentThread.GetHashCode()+"] Domain UNLOCKED!"); _locked = false; } } // See if we found a non-signaled work item at the head. if (bNotify) { // In both sync and async cases we just hand off the _locked state to // the next thread which will execute. if (nextWork.IsAsync()) { // Async-WorkItem: signal ThreadPool event to release one thread _asyncWorkEvent.Set(); //DBGConsole.WriteLine(Thread.CurrentThread.GetHashCode()+"] ### Signal " + nextWork._thread.GetHashCode() + (nextWork.IsDummy()?" DUMMY ":" REAL ")); } else { // Sync-WorkItem: notify the waiting sync-thread. lock (nextWork) { Monitor.Pulse(nextWork); //DBGConsole.WriteLine(Thread.CurrentThread.GetHashCode()+"] ~~~ Notify " + nextWork._thread.GetHashCode() + (nextWork.IsDummy()?" DUMMY ":" REAL ") ); } } } }
// Token: 0x060057D7 RID: 22487 RVA: 0x00134B30 File Offset: 0x00132D30 internal virtual void HandleWorkRequest(WorkItem work) { if (!this.IsNestedCall(work._reqMsg)) { if (work.IsAsync()) { bool flag = true; Queue workItemQueue = this._workItemQueue; lock (workItemQueue) { work.SetWaiting(); this._workItemQueue.Enqueue(work); if (!this._locked && this._workItemQueue.Count == 1) { work.SetSignaled(); this._locked = true; this._asyncWorkEvent.Set(); } return; } } lock (work) { Queue workItemQueue2 = this._workItemQueue; bool flag; lock (workItemQueue2) { if (!this._locked && this._workItemQueue.Count == 0) { this._locked = true; flag = false; } else { flag = true; work.SetWaiting(); this._workItemQueue.Enqueue(work); } } if (flag) { Monitor.Wait(work); if (!work.IsDummy()) { this.DispatcherCallBack(null, true); return; } Queue workItemQueue3 = this._workItemQueue; lock (workItemQueue3) { this._workItemQueue.Dequeue(); return; } } if (!work.IsDummy()) { work.SetSignaled(); this.ExecuteWorkItem(work); this.HandleWorkCompletion(); } return; } } work.SetSignaled(); work.Execute(); }
/* * This is called by any new incoming thread or from * HandleThreadReEntry() when a call-out thread wants to * re-enter the domain. * In the latter case, the WorkItem is a dummy item, it * just serves the purpose of something to block on till * the thread is given a green signal to re-enter. */ internal virtual void HandleWorkRequest(WorkItem work) { // < bool bQueued; // Check for nested call backs if (!IsNestedCall(work._reqMsg)) { // See what type of work it is if (work.IsAsync()) { // Async work is always queued. bQueued = true; // Enqueue the workItem lock (_workItemQueue) { //DBGConsole.WriteLine(Thread.CurrentThread.GetHashCode()+"] ### Async Item EnQueue " + work._thread.GetHashCode()); work.SetWaiting(); _workItemQueue.Enqueue(work); // If this is the only work item in the queue we will // have to trigger the thread-pool event ourselves if ( (!_locked) && (_workItemQueue.Count == 1) ) { //DBGConsole.WriteLine(Thread.CurrentThread.GetHashCode()+"] ### Async Signal Self: " + work._thread.GetHashCode()); work.SetSignaled(); //DBGConsole.WriteLine(Thread.CurrentThread.GetHashCode()+"] ### Domain Locked!"); _locked = true; _asyncWorkEvent.Set(); } } } else { // [....] work is queued only if there are other items // already in the queue. lock(work) { // Enqueue if we need to lock(_workItemQueue) { if ((!_locked) && (_workItemQueue.Count == 0)) { _locked = true; //DBGConsole.WriteLine(Thread.CurrentThread.GetHashCode()+"] ### Domain Locked!"); bQueued = false; } else { //DBGConsole.WriteLine(Thread.CurrentThread.GetHashCode()+"] ~~~ ENQUEUE [....]!" + (work.IsDummy()?" DUMMY ":" REAL ") + work._thread); bQueued = true; work.SetWaiting(); _workItemQueue.Enqueue(work); } } if (bQueued == true) { // If we queued a work item we must wait for some // other thread to peek at it and Notify us. //DBGConsole.WriteLine(Thread.CurrentThread.GetHashCode()+"] ~~~ WORK::WAIT" + work._thread); Monitor.Wait(work); //DBGConsole.WriteLine(Thread.CurrentThread.GetHashCode()+"] ~~~ FINISH Work::WAIT" + work._thread); Contract.Assert(_locked==true,"_locked==true"); // Our turn to complete the work! // Execute the callBack only if this is real work if (!work.IsDummy()) { //DBGConsole.WriteLine(Thread.CurrentThread.GetHashCode()+"] ~~~ Invoke DispatcherCallBack " + work._thread); // We invoke the callback here that does exactly // what we need to do ... dequeue work, execute, checkForMore DispatcherCallBack(null, true); } else { // DummyWork is just use to block/unblock a returning call. // Throw away our dummy WorkItem. lock(_workItemQueue) { _workItemQueue.Dequeue(); } // We don't check for more work here since we are already // in the midst of an executing WorkItem (at the end of which // the check will be performed) } } else { // We did not queue the work item. if (!work.IsDummy()) { //DBGConsole.WriteLine(Thread.CurrentThread.GetHashCode()+"] ~~~ Execute direct" + work._thread); // Execute the work. Contract.Assert(_locked==true,"_locked==true"); work.SetSignaled(); ExecuteWorkItem(work); // Check for more work HandleWorkCompletion(); } } } } } else { // We allow the nested calls to execute directly //DBGConsole.WriteLine(Thread.CurrentThread.GetHashCode()+"] ~~~ Execute Nested Call direct" + work._thread); // Execute the work. Contract.Assert(_locked==true,"_locked==true"); work.SetSignaled(); work.Execute(); // We are still inside the top level call ... // so after work.Execute finishes we don't check for more work // or unlock the domain as we do elsewhere. } }
internal virtual void HandleWorkRequest(WorkItem work) { if (!this.IsNestedCall(work._reqMsg)) { bool flag; if (work.IsAsync()) { flag = true; lock (this._workItemQueue) { work.SetWaiting(); this._workItemQueue.Enqueue(work); if (!this._locked && (this._workItemQueue.Count == 1)) { work.SetSignaled(); this._locked = true; this._asyncWorkEvent.Set(); } return; } } lock (work) { lock (this._workItemQueue) { if (!this._locked && (this._workItemQueue.Count == 0)) { this._locked = true; flag = false; } else { flag = true; work.SetWaiting(); this._workItemQueue.Enqueue(work); } } if (flag) { Monitor.Wait(work); if (!work.IsDummy()) { this.DispatcherCallBack(null, true); return; } lock (this._workItemQueue) { this._workItemQueue.Dequeue(); return; } } if (!work.IsDummy()) { work.SetSignaled(); this.ExecuteWorkItem(work); this.HandleWorkCompletion(); } return; } } work.SetSignaled(); work.Execute(); }
/* * This is called by any new incoming thread or from * HandleThreadReEntry() when a call-out thread wants to * re-enter the domain. * In the latter case, the WorkItem is a dummy item, it * just serves the purpose of something to block on till * the thread is given a green signal to re-enter. */ internal virtual void HandleWorkRequest(WorkItem work) { // < bool bQueued; // Check for nested call backs if (!IsNestedCall(work._reqMsg)) { // See what type of work it is if (work.IsAsync()) { // Async work is always queued. bQueued = true; // Enqueue the workItem lock (_workItemQueue) { //DBGConsole.WriteLine(Thread.CurrentThread.GetHashCode()+"] ### Async Item EnQueue " + work._thread.GetHashCode()); work.SetWaiting(); _workItemQueue.Enqueue(work); // If this is the only work item in the queue we will // have to trigger the thread-pool event ourselves if ((!_locked) && (_workItemQueue.Count == 1)) { //DBGConsole.WriteLine(Thread.CurrentThread.GetHashCode()+"] ### Async Signal Self: " + work._thread.GetHashCode()); work.SetSignaled(); //DBGConsole.WriteLine(Thread.CurrentThread.GetHashCode()+"] ### Domain Locked!"); _locked = true; _asyncWorkEvent.Set(); } } } else { // Sync work is queued only if there are other items // already in the queue. lock (work) { // Enqueue if we need to lock (_workItemQueue) { if ((!_locked) && (_workItemQueue.Count == 0)) { _locked = true; //DBGConsole.WriteLine(Thread.CurrentThread.GetHashCode()+"] ### Domain Locked!"); bQueued = false; } else { //DBGConsole.WriteLine(Thread.CurrentThread.GetHashCode()+"] ~~~ ENQUEUE Sync!" + (work.IsDummy()?" DUMMY ":" REAL ") + work._thread); bQueued = true; work.SetWaiting(); _workItemQueue.Enqueue(work); } } if (bQueued == true) { // If we queued a work item we must wait for some // other thread to peek at it and Notify us. //DBGConsole.WriteLine(Thread.CurrentThread.GetHashCode()+"] ~~~ WORK::WAIT" + work._thread); Monitor.Wait(work); //DBGConsole.WriteLine(Thread.CurrentThread.GetHashCode()+"] ~~~ FINISH Work::WAIT" + work._thread); Contract.Assert(_locked == true, "_locked==true"); // Our turn to complete the work! // Execute the callBack only if this is real work if (!work.IsDummy()) { //DBGConsole.WriteLine(Thread.CurrentThread.GetHashCode()+"] ~~~ Invoke DispatcherCallBack " + work._thread); // We invoke the callback here that does exactly // what we need to do ... dequeue work, execute, checkForMore DispatcherCallBack(null, true); } else { // DummyWork is just use to block/unblock a returning call. // Throw away our dummy WorkItem. lock (_workItemQueue) { _workItemQueue.Dequeue(); } // We don't check for more work here since we are already // in the midst of an executing WorkItem (at the end of which // the check will be performed) } } else { // We did not queue the work item. if (!work.IsDummy()) { //DBGConsole.WriteLine(Thread.CurrentThread.GetHashCode()+"] ~~~ Execute direct" + work._thread); // Execute the work. Contract.Assert(_locked == true, "_locked==true"); work.SetSignaled(); ExecuteWorkItem(work); // Check for more work HandleWorkCompletion(); } } } } } else { // We allow the nested calls to execute directly //DBGConsole.WriteLine(Thread.CurrentThread.GetHashCode()+"] ~~~ Execute Nested Call direct" + work._thread); // Execute the work. Contract.Assert(_locked == true, "_locked==true"); work.SetSignaled(); work.Execute(); // We are still inside the top level call ... // so after work.Execute finishes we don't check for more work // or unlock the domain as we do elsewhere. } }
internal virtual void HandleWorkRequest(WorkItem work) { if (!this.IsNestedCall(work._reqMsg)) { if (work.IsAsync()) { lock (this._workItemQueue) { work.SetWaiting(); this._workItemQueue.Enqueue((object)work); if (this._locked || this._workItemQueue.Count != 1) { return; } work.SetSignaled(); this._locked = true; this._asyncWorkEvent.Set(); } } else { lock (work) { bool local_0_1; lock (this._workItemQueue) { if (!this._locked && this._workItemQueue.Count == 0) { this._locked = true; local_0_1 = false; } else { local_0_1 = true; work.SetWaiting(); this._workItemQueue.Enqueue((object)work); } } if (local_0_1) { Monitor.Wait((object)work); if (!work.IsDummy()) { this.DispatcherCallBack((object)null, true); } else { lock (this._workItemQueue) this._workItemQueue.Dequeue(); } } else { if (work.IsDummy()) { return; } work.SetSignaled(); this.ExecuteWorkItem(work); this.HandleWorkCompletion(); } } } } else { work.SetSignaled(); work.Execute(); } }