From be9eb84f891f05d9cb809fda4ea4c3c133832c80 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Mussche?= Date: Fri, 1 Aug 2014 12:19:25 +0200 Subject: [PATCH] fixed locks and memleak --- IdHTTPWebsocketClient.pas | 112 ++++++++++++++++++++++---------------- IdSocketIOHandling.pas | 12 ++-- 2 files changed, 72 insertions(+), 52 deletions(-) diff --git a/IdHTTPWebsocketClient.pas b/IdHTTPWebsocketClient.pas index 8d86901..83ba9ed 100644 --- a/IdHTTPWebsocketClient.pas +++ b/IdHTTPWebsocketClient.pas @@ -236,7 +236,8 @@ begin // FHeartBeat.Enabled := False; // FHeartBeat.OnTimer := HeartBeatTimer; - FWriteTimeout := 2 * 1000; + FWriteTimeout := 2 * 1000; + ConnectTimeout := 2000; end; procedure TIdHTTPWebsocketClient.AsyncDispatchEvent(const aEvent: TStream); @@ -367,24 +368,30 @@ begin FSocketIO.WriteDisConnect(FSocketIOContext as TSocketIOContext) else FSocketIO.FreeConnection(FSocketIOContext as TSocketIOContext); + // IInterface(FSocketIOContext)._Release; FSocketIOContext := nil; - if IOHandler <> nil then - begin - IOHandler.Lock; - try - IOHandler.IsWebsocket := False; + Lock; + try + if IOHandler <> nil then + begin + IOHandler.Lock; + try + IOHandler.IsWebsocket := False; - inherited DisConnect(ANotifyPeer); - //clear buffer, other still "connected" - IOHandler.Clear; + inherited DisConnect(ANotifyPeer); + //clear buffer, other still "connected" + IOHandler.Clear; - //IOHandler.Free; - //IOHandler := TIdIOHandlerWebsocket.Create(nil); - finally - IOHandler.Unlock; + //IOHandler.Free; + //IOHandler := TIdIOHandlerWebsocket.Create(nil); + finally + IOHandler.Unlock; + end; end; + finally + UnLock; end; end; @@ -779,29 +786,34 @@ procedure TIdHTTPWebsocketClient.Ping; var ws: TIdIOHandlerWebsocket; begin - ws := IOHandler as TIdIOHandlerWebsocket; - ws.LastPingTime := Now; + if TryLock then + try + ws := IOHandler as TIdIOHandlerWebsocket; + ws.LastPingTime := Now; - //socket.io? - if SocketIOCompatible and ws.IsWebsocket then - begin - FSocketIO.Lock; - try - if (FSocketIOContext <> nil) then - FSocketIO.WritePing(FSocketIOContext as TSocketIOContext); //heartbeat socket.io message - finally - FSocketIO.UnLock; + //socket.io? + if SocketIOCompatible and ws.IsWebsocket then + begin + FSocketIO.Lock; + try + if (FSocketIOContext <> nil) then + FSocketIO.WritePing(FSocketIOContext as TSocketIOContext); //heartbeat socket.io message + finally + FSocketIO.UnLock; + end end - end - //only websocket? - else if not SocketIOCompatible and ws.IsWebsocket then - begin - if ws.TryLock then - try - ws.WriteData(nil, wdcPing); - finally - ws.Unlock; + //only websocket? + else if not SocketIOCompatible and ws.IsWebsocket then + begin + if ws.TryLock then + try + ws.WriteData(nil, wdcPing); + finally + ws.Unlock; + end; end; + finally + Unlock; end; end; @@ -1244,6 +1256,9 @@ begin FReconnectThread.Free; end; + if FReconnectlist <> nil then + FReconnectlist.Free; + IdWinsock2.closesocket(FTempHandle); FTempHandle := 0; FChannels.Free; @@ -1508,24 +1523,29 @@ begin chn := TIdHTTPWebsocketClient(l.Items[i]); if chn.NoAsyncRead then Continue; - ws := chn.IOHandler as TIdIOHandlerWebsocket; - if (ws = nil) then Continue; - - if ws.TryLock then //IOHandler.Readable cannot be done during pending action! + if chn.TryLock then try + ws := chn.IOHandler as TIdIOHandlerWebsocket; + if (ws = nil) then Continue; + + if ws.TryLock then //IOHandler.Readable cannot be done during pending action! try - chn.ReadAndProcessData; - except - on e:Exception do - begin - l := nil; - FChannels.UnlockList; - chn.ResetChannel; - //raise; + try + chn.ReadAndProcessData; + except + on e:Exception do + begin + l := nil; + FChannels.UnlockList; + chn.ResetChannel; + //raise; + end; end; + finally + ws.Unlock; end; finally - ws.Unlock; + chn.Unlock; end; end; diff --git a/IdSocketIOHandling.pas b/IdSocketIOHandling.pas index 4aaecda..7a7acf1 100644 --- a/IdSocketIOHandling.pas +++ b/IdSocketIOHandling.pas @@ -186,7 +186,7 @@ type procedure WriteSocketIOJSON(const ASocket: ISocketIOContext; const aRoom, aJSON: string; aCallback: TSocketIOCallbackRef = nil; const aOnError: TSocketIOError = nil); procedure WriteSocketIOEvent(const ASocket: ISocketIOContext; const aRoom, aEventName, aJSONArray: string; aCallback: TSocketIOCallback; const aOnError: TSocketIOError); procedure WriteSocketIOEventRef(const ASocket: ISocketIOContext; const aRoom, aEventName, aJSONArray: string; aCallback: TSocketIOCallbackRef; const aOnError: TSocketIOError); - function WriteSocketIOEventSync(const ASocket: ISocketIOContext; const aRoom, aEventName, aJSONArray: string; aMaxwait_ms: Integer = INFINITE): ISuperObject; + function WriteSocketIOEventSync(const ASocket: ISocketIOContext; const aRoom, aEventName, aJSONArray: string; aMaxwait_ms: Cardinal = INFINITE): ISuperObject; procedure WriteSocketIOResult(const ASocket: ISocketIOContext; aRequestMsgNr: Integer; const aRoom, aData: string); procedure ProcessSocketIO_XHR(const aGUID: string; const aStrmRequest, aStrmResponse: TStream); @@ -229,7 +229,7 @@ type public procedure Send(const aMessage: string; const aCallback: TSocketIOMsgJSON = nil; const aOnError: TSocketIOError = nil); procedure Emit(const aEventName: string; const aData: ISuperObject; const aCallback: TSocketIOMsgJSON = nil; const aOnError: TSocketIOError = nil);overload; - function EmitSync(const aEventName: string; const aData: ISuperObject; aMaxwait_ms: Integer = INFINITE): ISuperobject; + function EmitSync(const aEventName: string; const aData: ISuperObject; aMaxwait_ms: Cardinal = INFINITE): ISuperobject; //procedure Emit(const aEventName: string; const aData: string; const aCallback: TSocketIOMsgJSON = nil; const aOnError: TSocketIOError = nil);overload; end; @@ -760,7 +760,7 @@ begin begin Lock; try - ASocket._AddRef; + //ASocket._AddRef; FConnections.Add(nil, socket); //clients do not have a TIdContext? finally UnLock; @@ -949,7 +949,7 @@ begin if not FConnections.ContainsValue(ASocket) and not FConnectionsGUID.ContainsValue(ASocket) then begin - ASocket._AddRef; + //ASocket._AddRef; FConnections.Add(nil, ASocket); //clients do not have a TIdContext? end; @@ -1050,7 +1050,7 @@ begin end; function TIdBaseSocketIOHandling.WriteSocketIOEventSync(const ASocket: ISocketIOContext; const aRoom, aEventName, - aJSONArray: string; aMaxwait_ms: Integer = INFINITE): ISuperObject; + aJSONArray: string; aMaxwait_ms: Cardinal = INFINITE): ISuperObject; var sresult: string; inr: Integer; @@ -1579,7 +1579,7 @@ begin end; end; -function TIdSocketIOHandling.EmitSync(const aEventName: string; const aData: ISuperObject; aMaxwait_ms: Integer = INFINITE): ISuperobject; +function TIdSocketIOHandling.EmitSync(const aEventName: string; const aData: ISuperObject; aMaxwait_ms: Cardinal = INFINITE): ISuperobject; var firstcontext, context: ISocketIOContext; jsonarray: string;