Wed Nov 8 16:40:02 CET 2006 Paolo Molaro <lupus@ximian.com>
[mono.git] / mcs / class / System / System.Net.Sockets / GHSocketFactory.cs
1 using System;\r
2 using System.Net;\r
3 \r
4 namespace System.Net.Sockets\r
5 {\r
6         /// <summary>\r
7         /// Summary description for GHSocketFactory.\r
8         /// </summary>\r
9         public class GHSocketFactory\r
10         {\r
11                 internal static GHSocket Socket_internal(AddressFamily family,\r
12                                                                                                  SocketType type,\r
13                                                                                                  ProtocolType proto,\r
14                                                                                                  out int error)\r
15                 {\r
16                         if ( family == AddressFamily.InterNetwork &&\r
17                                 //(family == AddressFamily.InterNetwork || family == AddressFamily.InterNetworkV6) &&\r
18                                 (type == SocketType.Stream || type == SocketType.Unknown) &&\r
19                                 (proto == ProtocolType.Tcp || proto == ProtocolType.Unknown || proto == ProtocolType.Unspecified) )\r
20                         {\r
21                                 error = 0;\r
22                                 return new GHStreamSocket();\r
23                         }\r
24 \r
25                         error = 10044; //WSAESOCKTNOSUPPORT (Socket type not supported)\r
26                         return null;\r
27                 }\r
28 \r
29                 internal static void Select_internal (ref Socket [] sockets, int microSeconds, out int error)\r
30                 {\r
31                         error = 0;\r
32 \r
33                         java.nio.channels.Selector selector = java.nio.channels.Selector.open();\r
34 \r
35                         int mode = 0;\r
36                         int count = sockets.Length;\r
37                         for (int i = 0; i < count; i++) \r
38                         {\r
39                                 if (sockets [i] == null) \r
40                                 { // separator\r
41                                         mode++;\r
42                                         continue;\r
43                                 }\r
44 \r
45                                 GHSocket sock = sockets [i].GHHandle;\r
46                                 if (sock == null)\r
47                                 {\r
48                                         throw new ArgumentNullException ("GHSocket handle is null");\r
49                                 }\r
50 \r
51                                 sock.RegisterSelector(selector, mode, sockets [i], out error);\r
52                                 if (error != 0)\r
53                                 {\r
54                                         error = 0;\r
55                                         sockets = null;\r
56                                         CloseSelector(selector);\r
57                                         return;\r
58                                 }\r
59                         }\r
60                         \r
61                         sockets = null;\r
62 \r
63                         long timeOutMillis = 1;\r
64                         if (microSeconds < 0)\r
65                         {\r
66                                 timeOutMillis = 0;\r
67                         } \r
68                         else if (microSeconds > 999)\r
69                         {\r
70                                 timeOutMillis = (long)(microSeconds / 1000);\r
71                         }\r
72 \r
73                         int readyCount = 0;\r
74                         try\r
75                         {\r
76                                 readyCount = selector.select(timeOutMillis);\r
77                         }\r
78                         catch (Exception e)\r
79                         {\r
80                                 error = 10022; //WSAEINVAL (Invalid argument)\r
81 #if DEBUG\r
82                                 Console.WriteLine("Caught exception during Select_internal selector.select - {0}: {1}\n{2}", e.GetType(), e.Message, e.StackTrace);\r
83 #endif\r
84                         }\r
85 \r
86                         if (readyCount > 0)\r
87                         {\r
88                                 try\r
89                                 {\r
90                                         sockets = new Socket[readyCount+2];\r
91                                         Socket[] writeList = new Socket[readyCount];\r
92                                         Socket[] errorList = new Socket[readyCount];\r
93 \r
94                                         int readListCount = 0;\r
95                                         int writeListCount = 0;\r
96                                         int errorListCount = 0;\r
97 \r
98                                         java.util.Set readyKeys = selector.selectedKeys();\r
99                                         java.util.Iterator it = readyKeys.iterator();\r
100 \r
101                                         while (it.hasNext()) \r
102                                         {\r
103                                                 java.nio.channels.SelectionKey key = (java.nio.channels.SelectionKey)it.next();\r
104                 \r
105                                                 if (key.isAcceptable() || key.isReadable()) \r
106                                                 {\r
107                                                         sockets[readListCount] = (Socket)key.attachment();\r
108                                                         readListCount++;\r
109                                                 }\r
110                                                 if (key.isWritable()) \r
111                                                 {\r
112                                                         writeList[writeListCount] = (Socket)key.attachment();\r
113                                                         writeListCount++;\r
114                                                 }\r
115                                                 if (key.isConnectable()) \r
116                                                 {\r
117                                                         Socket source = (Socket)key.attachment();\r
118                                                         if (source.GHHandle.CheckConnectionFinished())\r
119                                                         {\r
120                                                                 writeList[writeListCount] = source;\r
121                                                                 writeListCount++;\r
122                                                         }\r
123                                                         else\r
124                                                         {\r
125                                                                 errorList[errorListCount] = source;\r
126                                                                 errorListCount++;\r
127                                                         }\r
128                                                 }\r
129                                         }\r
130 \r
131                                         sockets[readListCount] = null;\r
132                                         readListCount++;\r
133                                         for (int i = 0; i < writeListCount; i++, readListCount++)\r
134                                         {\r
135                                                 sockets[readListCount] = writeList[i];\r
136                                         }\r
137                                         sockets[readListCount] = null;\r
138                                         readListCount++;\r
139                                         for (int i = 0; i < errorListCount; i++, readListCount++)\r
140                                         {\r
141                                                 sockets[readListCount] = errorList[i];\r
142                                         }\r
143                                 }\r
144                                 catch (Exception e)\r
145                                 {\r
146                                         error = 10022; //WSAEINVAL (Invalid argument)\r
147 #if DEBUG\r
148                                         Console.WriteLine("Caught exception during Select_internal iterate selected keys - {0}: {1}\n{2}", e.GetType(), e.Message, e.StackTrace);\r
149 #endif\r
150                                 }\r
151                         }\r
152 \r
153                         CloseSelector(selector);\r
154                 }\r
155 \r
156                 internal static void CloseSelector (java.nio.channels.Selector selector)\r
157                 {\r
158                         java.util.Set keys = selector.keys();\r
159                         java.util.Iterator it = keys.iterator();\r
160 \r
161                         try\r
162                         {\r
163                                 selector.close();\r
164                         }\r
165                         catch (Exception e)\r
166                         {\r
167 #if DEBUG\r
168                                 Console.WriteLine("Caught exception during CloseSelector selector.close - {0}: {1}\n{2}", e.GetType(), e.Message, e.StackTrace);\r
169 #endif\r
170                         }\r
171 \r
172                         while (it.hasNext()) \r
173                         {\r
174                                 java.nio.channels.SelectionKey key = (java.nio.channels.SelectionKey)it.next();\r
175                                 Socket source = (Socket)key.attachment();\r
176                                 try\r
177                                 {\r
178                                         if (source.Blocking)\r
179                                         {\r
180                                                 /*\r
181                                                         A channel must be placed into non-blocking mode before being registered \r
182                                                         with a selector, and may not be returned to blocking mode until it has been \r
183                                                         deregistered. So, I need set the channel back to the blocking mode, if it was\r
184                                                         in blocking mode before select operation\r
185                                                 */\r
186                                                 source.Blocking = true;\r
187                                         }\r
188                                 }\r
189                                 catch (Exception be)\r
190                                 {\r
191 #if DEBUG\r
192                                         Console.WriteLine("Caught exception during CloseSelector source.Blocking - {0}: {1}\n{2}", be.GetType(), be.Message, be.StackTrace);\r
193 #endif\r
194                                 }\r
195                         }\r
196                 }\r
197         }\r
198 }\r