public static int WaitAny(NwiWaitHandle[] waitHandles) { int ret = WaitHandle.WaitTimeout; int size = waitHandles.Length; while (true) { bool isAnySet = false; for (int i = 0; i < size; ++i) { if (waitHandles[i].WaitOne(0)) { isAnySet = true; ret = i; break; } } if (isAnySet) break; Thread.Sleep(MILLISECONDS_TIMEOUT); } return ret; }
public static bool WaitAll(NwiWaitHandle[] waitHandles, int millisecondsTimeout) { bool ret = true; int cnt = millisecondsTimeout / MILLISECONDS_TIMEOUT; while (true) { bool isAllSet = true; foreach (NwiWaitHandle handle in waitHandles) { if (!handle.WaitOne(0)) { isAllSet = false; break; } } if (isAllSet) { break; } else if (cnt-- <= 0) { ret = false; break; } Thread.Sleep(MILLISECONDS_TIMEOUT); } return ret; }
public static bool WaitAll(NwiWaitHandle[] waitHandles) { bool ret = true; while (true) { bool isAllSet = true; foreach (NwiWaitHandle handle in waitHandles) { if (!handle.WaitOne(0)) { isAllSet = false; break; } } if (isAllSet) break; Thread.Sleep(MILLISECONDS_TIMEOUT); } return ret; }
private void ConnectThread() { uint errCode = (uint)ErrCode.Success; int loopCnt = 3; Log(string.Format("[VAAL] ConnectThread() : START")); lock (m_lockSocket) { CloseSocket(); m_buffer = new byte[0]; bool isFirst = true; while (true) { try { string ip; int port; m_eventConnect.Reset(); TcpClient client = new TcpClient(); client.NoDelay = true; if (isFirst) { isFirst = false; ip = m_proxyServer.LastConnectedServerIp; port = m_proxyServer.LastConnectedServerPort; } else { ip = m_proxyServer.ServerIp; port = m_proxyServer.ServerPort; m_proxyServer.SetLastConnectedServerInfo(ip, port); } Log(string.Format("[VAAL] ConnectThread({0}, {1}) : Try connecting...", ip, port)); //client.Connect(m_serverIp, m_serverPort); client.BeginConnect(ip, port, new AsyncCallback(ConnectCallback), client); NwiWaitHandle[] waitHandles = new NwiWaitHandle[2]; waitHandles[0] = m_eventThreadStop; waitHandles[1] = m_eventConnect; int index = NwiWaitHandle.WaitAny(waitHandles, 3000); if (index == 0) { Log("[VAAL] ConnectThread() : m_eventThreadStop signaled"); break; } if (client.Connected) { Log(string.Format("[VAAL] ConnectThread() : Connected")); m_socket = new IDSocket(client); m_socket.RecvPacketHandler = new RecvPacketHandler(OnRecvPacket); m_socket.ErrHandler = new ErrorHandler(OnErrorHandler); m_socket.LogHandler = new LogHandler(OnLogHandler); m_eventSocketError.Reset(); StartReadPacketThread(); Thread.Sleep(100); HelloPacket packet = new HelloPacket(); packet.m_ver1 = (ushort)Version.Ver1; packet.m_ver2 = (ushort)Version.Ver2; packet.m_clientProductVer = m_proxyServer.ProductVer; packet.m_configVer = (m_proxyServer.ServerConfig == null) ? (byte)0 : m_proxyServer.ServerConfig.Version; errCode = SendSyncPacket(m_socket, packet, m_proxyServer.SocketTimeout); if (errCode == (uint)ErrCode.Success) { if (m_packetCode == PacketCode.Hello) { errCode = m_resultCode; } else { errCode = (uint)ErrCode.WrongPacketCode; } } packet.Dispose(); break; } else { Log(string.Format("[VAAL] ConnectThread() : Not connected")); } } catch (Exception e) { Log(string.Format("[VAAL] ConnectThread() : Exception={0}", e.Message)); errCode = (uint)ErrCode.InternalException; } if (--loopCnt <= 0) { errCode = (uint)ErrCode.NetworkCantConnect; break; } else { Thread.Sleep(2000); } } if (errCode == (uint)ErrCode.Success && m_socket != null) { if (m_retryLoginPacket != null && (m_socketState == SocketState.Login || m_socketState == SocketState.Relogin)) { Log(string.Format("[VAAL] ConnectThread() : Send Relogin Packet")); m_retryLoginPacket.m_recvTransNum = m_recvTransNum; m_retryLoginPacket.m_isAlreadyLogined = (byte)((m_socketState == SocketState.Login) ? 0 : 1); m_isLoginPacketSync = true; errCode = SendSyncPacket(m_socket, m_retryLoginPacket, m_proxyServer.SocketTimeout); } else { m_socketState = SocketState.Ready; m_eventSendPacket.Set(); } } if (errCode != (uint)ErrCode.Success) { m_socketState = SocketState.Disconnected; } } if (errCode != (uint)ErrCode.Success) { // 락 m_lockSocket 을 소유하고 아래 함수를 호출하면 안된다. (deadlock 상황 발생할 수 있음) CallNotifyHandler(NotifyEventCode.DisconnectFromServer, errCode, null, null); } Log(string.Format("[VAAL] ConnectThread() : END (EC={0}, SS={1})", errCode, m_socketState)); }
private void WatchPacketThread() { Log(string.Format("[VAAL] WatchPacketThread() : START")); bool isThreadStopped = false; NwiWaitHandle[] handles = new NwiWaitHandle[2]; handles[0] = m_eventThreadStop; handles[1] = m_eventWatchPacket; while (!isThreadStopped) { Log(string.Format("[VAAL] WatchPacketThread() : Before WaitAny(handles)")); int index = NwiWaitHandle.WaitAny(handles); Log(string.Format("[VAAL] WatchPacketThread() : After WaitAny(handles) : index={0}", index)); switch (index) { case 0: isThreadStopped = true; break; case 1: while (true) { RetryPacket rp = null; NwiWaitHandle[] handles2 = new NwiWaitHandle[3]; handles2[0] = m_eventThreadStop; handles2[1] = m_eventSocketError; lock (m_retryPackets) { if (m_retryPackets.Count == 0) { Log("[VAAL] WatchPacketThread() : m_retryPackets.Count == 0"); break; } rp = m_retryPackets[0]; if (rp.m_event.WaitOne(0)) { rp.m_packet.Dispose(); m_retryPackets.Remove(rp); Log(string.Format("[VAAL] WatchPacketThread() : rp.m_event signaled : {0}", rp.m_nec)); continue; } handles2[2] = rp.m_event; } Log(string.Format("[VAAL] WatchPacketThread() : Before WaitAny(handles2) : {0}", rp.m_nec)); int index2 = NwiWaitHandle.WaitAny(handles2, m_proxyServer.SocketTimeout); Log(string.Format("[VAAL] WatchPacketThread() : After WaitAny(handles2) : index2={0}, {1}", index2, rp.m_nec)); if (index2 == 0) { isThreadStopped = true; break; } else if (index2 == 1) { break; } else if (index2 == 2) { } else { CallNotifyHandler(rp.m_nec, (uint)ErrCode.NetworkTimeout, null, null); break; } } break; default: isThreadStopped = true; CallNotifyHandler(NotifyEventCode.VaalWatchPacketThread, (uint)ErrCode.WatchPacketThreadTerminated, null, null); break; } } Log(string.Format("[VAAL] WatchSocketEvent() : END")); }
private void SendPacketThread() { Log(string.Format("[VAAL] SendPacketThread() : START")); bool isThreadStopped = false; NwiWaitHandle[] handles = new NwiWaitHandle[2]; handles[0] = m_eventThreadStop; handles[1] = m_eventSendPacket; while (!isThreadStopped) { int index = 0; Log(string.Format("[VAAL] SendPacketThread() : Before WaitAny")); if (m_proxyServer.KeepAliveInterval == 0) index = NwiWaitHandle.WaitAny(handles); else index = NwiWaitHandle.WaitAny(handles, m_proxyServer.KeepAliveInterval); Log(string.Format("[VAAL] SendPacketThread() : After WaitAny : index={0}", index)); switch (index) { case 0: isThreadStopped = true; break; case 1: if (m_socketState == SocketState.Connecting || m_socketState == SocketState.Relogin) { Log(string.Format("[VAAL] SendPacketThread() : SS={0}", m_socketState)); break; } lock (m_lockSocket) { if (m_socket == null) { if (m_socketState == SocketState.Disconnected) { m_socketState = SocketState.Connecting; Thread thread = new Thread(new ThreadStart(ConnectThread)); thread.IsBackground = true; thread.Start(); } break; } } while (m_socketState == SocketState.Ready) { RetryPacket rp = null; lock (m_sendingPackets) { if (m_sendingPackets.Count == 0) { Log("[VAAL] SendPacketThread() : m_sendingPackets.Count == 0"); break; } rp = m_sendingPackets[0]; m_sendingPackets.Remove(rp); } TwoWayPacket packet = (TwoWayPacket)rp.m_packet.Clone(); lock (m_retryPackets) { rp.m_event.Reset(); m_retryPackets.Add(rp); } try { // m_socket이 lock으로 보호되지 않는다. // 이는 SendPacket() 이 언제 리턴될지 모르기 때문. // WatchPacketThread()에서 타임아웃 걸리면, 소켓을 재연결하기 위해 여기서는 lock을 쓰지 않는다. m_eventWatchPacket.Set(); m_socket.SendPacket(packet); Log(string.Format("[VAAL] SendPacketThread() : Called SendPacket(). NC={0}", rp.m_nec)); } catch (Exception e) { Log(string.Format("[VAAL] SendPacketThread() : Exception while Sendpacket() : {0}", e.Message)); break; } finally { packet.Dispose(); } } break; case WaitHandle.WaitTimeout: uint errCode = KeepAlive(); Log(string.Format("[VAAL] SendPacketThread() : Called KeepAlive(). ({0})", errCode)); break; default: isThreadStopped = true; CallNotifyHandler(NotifyEventCode.VaalSendPacketThread, (uint)ErrCode.SendPacketThreadTerminated, null, null); break; } } Log("[VAAL] SendPacketThread() : END"); }
public static int WaitAny(NwiWaitHandle[] waitHandles, int millisecondsTimeout) { int ret = WaitHandle.WaitTimeout; int cnt = millisecondsTimeout / MILLISECONDS_TIMEOUT; int size = waitHandles.Length; while (true) { bool isAnySet = false; for (int i = 0; i < size; ++i) { if (waitHandles[i].WaitOne(0)) { isAnySet = true; ret = i; break; } } if (isAnySet) { break; } else if (cnt-- <= 0) { break; } Thread.Sleep(MILLISECONDS_TIMEOUT); } return ret; }