예제 #1
0
        private unsafe void ReadLoop()
        {
            for (;;)
            {
                streamHandler.FillReadBuffer(sizeof(ushort));
                fixed(byte *buf = &streamHandler.readBuffer[0])
                {
                    streamHandler.fixedReadBuffer = buf;
                    ushort callId;

                    streamHandler.Read(out callId);
                    RemoteCall newCall;

                    while (newCalls.TryTake(out newCall))
                    {
                        Stack <RemoteCall> stack;
                        if (!threadCallStack.TryGetValue(newCall.localThreadId, out stack))
                        {
                            stack = new Stack <RemoteCall>();
                            threadCallStack.Add(newCall.localThreadId, stack);
                        }
                        stack.Push(newCall);
                    }
                    if (callId == ushort.MaxValue)
                    {
                        int threadId;
                        streamHandler.Read(out threadId);
                        var rc = threadCallStack[threadId].Pop();
                        rc.ReadResponse(streamHandler);
                        lock (rc) {
                            Monitor.PulseAll(rc);
                        }
                    }
                    else
                    {
                        var call = RemoteCallFactory.ForCallId((RemoteCallId)callId);
                        call.ReadRequest(streamHandler);
                        if (call.localThreadId != 0)
                        {
                            var rc = threadCallStack[call.localThreadId].Peek();
                            rc.nextCall = call;
                            lock (rc) {
                                Monitor.PulseAll(rc);
                            }
                        }
                        else
                        {
                            WorkerPool.EnqueueTask(() => {
                                call.Execute(this);
                                if (!call.returnImmediately)
                                {
                                    Write(call.WriteResponse);
                                }
                            });
                        }
                    }
                    streamHandler.fixedReadBuffer = null;
                }
            }
        }