3 * Copyright (C)2007-2008 Versabanq Innovations Inc. and contributors.
4 * See the included file named LICENSE for license information.
7 using System
.Net
.Sockets
;
8 using System
.Collections
;
9 using System
.Collections
.Generic
;
11 using System
.Threading
;
13 public interface IWvEventer
15 void runonce(int msec_timeout
);
17 void onreadable(Socket s
, Action a
);
18 void onwritable(Socket s
, Action a
);
19 void addpending(Object cookie
, Action a
);
20 void delpending(Object cookie
);
21 void addtimeout(Object cookie
, DateTime t
, Action a
);
22 void deltimeout(Object cookie
);
25 public class WvEventer
: IWvEventer
27 // CAREFUL! The 'pending' structure might be accessed from other threads!
28 Dictionary
<object, Action
>
29 pending
= new Dictionary
<object, Action
>();
31 Dictionary
<Socket
, Action
>
32 r
= new Dictionary
<Socket
, Action
>(),
33 w
= new Dictionary
<Socket
, Action
>();
40 public TimeAction(DateTime t
, Action a
)
46 Dictionary
<Object
, TimeAction
>
47 ta
= new Dictionary
<Object
, TimeAction
>();
53 public void onreadable(Socket s
, Action a
)
55 if (s
== null) return;
61 public void onwritable(Socket s
, Action a
)
63 if (s
== null) return;
69 public void addtimeout(Object cookie
, DateTime t
, Action a
)
73 ta
.Add(cookie
, new TimeAction(t
, a
));
77 // This is the only kind of event you can enqueue from a thread other
78 // than the one doing runonce()!
79 // It will run your Action in the runonce() thread on the next pass.
80 public void addpending(Object cookie
, Action a
)
84 pending
.Remove(cookie
);
85 pending
.Add(cookie
, a
);
89 public void delpending(Object cookie
)
93 pending
.Remove(cookie
);
97 public void deltimeout(Object cookie
)
102 public void runonce()
107 public void runonce(int msec_timeout
)
109 // Console.WriteLine("Pending: {0}", pending.Count);
111 IList
<Socket
> rlist
= r
.Keys
.ToList();
112 IList
<Socket
> wlist
= w
.Keys
.ToList();
113 IList
<TimeAction
> talist
= ta
.Values
.ToList();
114 if (msec_timeout
< 0)
115 msec_timeout
= 1000000;
117 = new TimeAction(DateTime
.Now
118 + TimeSpan
.FromMilliseconds(msec_timeout
), null);
120 foreach (TimeAction t
in talist
)
124 TimeSpan timeout
= first
.t
- DateTime
.Now
;
125 if (timeout
< TimeSpan
.Zero
)
126 timeout
= TimeSpan
.Zero
;
130 if (pending
.Count
> 0)
131 timeout
= TimeSpan
.Zero
;
134 if (rlist
.Count
== 0 && wlist
.Count
== 0)
136 // Socket.Select throws an exception if all lists are empty;
138 if (timeout
> TimeSpan
.Zero
)
139 Thread
.Sleep((int)timeout
.TotalMilliseconds
);
143 Socket
.Select((IList
)rlist
, (IList
)wlist
, null,
144 (int)timeout
.TotalMilliseconds
* 1000);
147 DateTime now
= DateTime
.Now
;
148 foreach (Socket s
in rlist
)
150 foreach (Socket s
in wlist
)
152 foreach (Object cookie
in ta
.Keys
)
154 TimeAction t
= ta
[cookie
];
165 nowpending
= pending
.Values
.ToArray();
168 // Console.WriteLine("NowPending: {0}", nowpending.Length);
169 foreach (Action a
in nowpending
)