void CJavaDebugAgentDriver::ClientDisconnected(CTcpServerHandler* aHandler) { TInt handlerPos = iHandlers.Find(aHandler); if (handlerPos >= 0) { TInetAddr remote; RSocket* socket = aHandler->Socket(); socket->LocalName(remote); // Delete a matching KeepAlive object. It doesn't matter which one. // Ideally we shouldn't create more than one KeepAlive per address // but we normally have no more than one client, so it's doesn't // really matter. for (TInt i = 0; i<iKeepAliveList.Count(); i++) { if (remote.Match(iKeepAliveList[i]->Address())) { delete iKeepAliveList[i]; iKeepAliveList.Remove(i); break; } } // It's not obvious how we can recover from the situation when // we can't this handler to iDeadHandlers array. It's not safe // to delete the handler here because this callback is invoked // by the handler, and it may access its this pointer after this // callback has returned. It that case, let's leave it in iHandlers // array. It screws things up but at least we don't leak memory. // Hopefully, this won't happen too often... if (iDeadHandlers.Append(aHandler) == KErrNone) { iHandlers.Remove(handlerPos); if (iHandlers.Count() == 0) { // It was our last client SetState(iServer ? EListening : EDisconnected); } // Schedule callback on a clean stack where we can safely // delete the handler iAsyncCleanup->CallBack(); } } //Dima: Cleanup on start in InitL conflicts with installation //seemingly due to errors in Installer (ECOM framework panics //on loading midp2installerplugin.dll on installation after cleanup) //so we clean up on client disconnect. if (IsAutoCleanEnabled()) { Log(_L("Cleaning up old data...")); iEngine->Cleanup(); Log(_L("Done cleaning...")); } }
// Notifications from CTcpServerHandler void CJavaDebugAgentDriver::ClientConnected(CTcpServerHandler* aHandler) { if (iHandlers.Append(aHandler) == KErrNone) { if (iKeepAlivePeriod > 0) { TInetAddr local; TInetAddr remote; aHandler->Socket()->LocalName(local); aHandler->Socket()->RemoteName(remote); // No ping for local connections (as in case of debugging over // Bluetooth) if (!local.Match(remote)) { TRAPD(err, InitKeepAliveL(&remote)); if (err == KErrNone) { iLog->Log(_S("Starting keep-alive timer")); } else { // Ignore the error, it shoudn't be fatal iLog->LogFormat(_S("Keep-alive error %d"),err); } } } if (iHandlers.Count() == 1) { // First client SetState(EConnected); } } else { // This connection will work but we will leak some memory. // Suggest the user to restart the application iLog->Log(_S("Internal error. Please restart debug agent.")); } }
//-- compares 2 IP addresses, for array search. TBool IPAddrIsEqual(const TInetAddr& aFirst, const TInetAddr& aSecond) { return aFirst.Match(aSecond); }