|
using System;
using System.Collections;
using System.IO;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Security.Principal;
using System.Runtime.Remoting.Messaging;
using System.Threading;
namespace Reachability
{
class Semaphore
{
public Semaphore(int maxCount)
{
_maxCount = maxCount;
_currentCount = 0;
}
public void Acquire()
{
lock(this)
{
while (_currentCount >= _maxCount)
{
Monitor.Wait(this, System.TimeSpan.FromSeconds(60));
}
++_currentCount;
}
}
public void Release()
{
lock(this)
{
_currentCount--;
Monitor.PulseAll(this);
}
}
private int _maxCount;
private int _currentCount;
}
public class SyncQueue : Queue
{
Semaphore sem;
public SyncQueue()
{
sem = new Semaphore(0);
}
public override void Enqueue(object obj)
{
base.Enqueue(obj);
sem.Release();
}
public override object Dequeue()
{
sem.Acquire();
return base.Dequeue();
}
}
public class Redirector : MarshalByRefObject
{
public Redirector()
{
}
public void GetNextRequest(Guid slot, out Message m)
{
SyncQueue q = reqs[slot] as SyncQueue;
if(q==null)reqs.Add(slot, q=new SyncQueue());
m = q.Dequeue() as Message;
}
public void ReturnResponse(Guid slot, Response r)
{
SyncQueue q = resps[slot] as SyncQueue;
if(q==null)resps.Add(slot, q=new SyncQueue());
q.Enqueue(r);
}
[Serializable]
public class Message
{
public bool oneway;
public ITransportHeaders requestHeaders;
public byte[] requestStream;
public IPrincipal callerPrincipal;
public Message(ITransportHeaders requestHeaders, byte[] requestStream, IPrincipal principal, bool oneway)
{
this.oneway=oneway;
this.requestHeaders=requestHeaders;
this.requestStream=requestStream;
this.callerPrincipal=principal;
}
}
[Serializable]
public class Response
{
public Response(ITransportHeaders h, Stream s)
{
this.responseHeaders=h;
responseStream = new byte[s.Length];
s.Read(responseStream, 0, responseStream.Length);
}
public ITransportHeaders responseHeaders;
public byte[] responseStream;
}
Hashtable reqs = Hashtable.Synchronized(new Hashtable());
Hashtable resps = Hashtable.Synchronized(new Hashtable());
// no longer listening incoming requests.
public void RevokeDestinationSlot(Guid slot)
{
SyncQueue q = reqs[slot] as SyncQueue;
q.Enqueue(new object());
reqs.Remove(slot);
resps.Remove(slot);
}
public void RedirectRequest(Guid slot, bool oneway, ITransportHeaders requestHeaders, byte[] requestStream, out ITransportHeaders responseHeaders, out byte[] responseStream)
{
SyncQueue q = reqs[slot] as SyncQueue;
if(q==null)reqs.Add(slot, q=new SyncQueue());
q.Enqueue(new Message(requestHeaders, requestStream, Thread.CurrentPrincipal, oneway));
if(!oneway)
{
q = resps[slot] as SyncQueue;
if(q==null)resps.Add(slot, q=new SyncQueue());
Response r = q.Dequeue() as Response;
responseHeaders = r.responseHeaders;
responseStream = r.responseStream;
}
else
{
responseHeaders = null;
responseStream = null;
}
}
}
}
|
By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.
If a file you wish to view isn't highlighted, and is a text file (not binary), please
let us know and we'll add colourisation support for it.
My name is Zhiheng Cao. I major in Eletronics Engineering, in University of Tokyo. I do part time jobs of computer programming and teaching high school students English and Mathematics.
CodeProject provided me with valuable information for my programming job many times in the past. I hope I can do my part by providing goodies I have.