connectivity/com.nokia.tcf/native/TCFNative/TCFClient/ClientManager.cpp
branchRCL_2_4
changeset 916 6743933eec70
parent 60 9d2210c8eed2
equal deleted inserted replaced
915:3b26c948790f 916:6743933eec70
   486 		m_ServerRunning = TRUE;
   486 		m_ServerRunning = TRUE;
   487 
   487 
   488 	TCDEBUGLOGA1("CClientManager::StartServer end numRefs = %d\n", pData->numRefs);
   488 	TCDEBUGLOGA1("CClientManager::StartServer end numRefs = %d\n", pData->numRefs);
   489 	return ret;
   489 	return ret;
   490 }
   490 }
   491 
   491 BOOL CClientManager::IsTCFServerActive(DWORD processId)
       
   492 {
       
   493 	HANDLE h = ::OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, processId);
       
   494 	if (h)
       
   495 	{
       
   496 		// is it really still alive?
       
   497 		DWORD exitCode = -5;
       
   498 		BOOL exitCall = ::GetExitCodeProcess(h, &exitCode);
       
   499 		::CloseHandle(h);
       
   500 		if (exitCall == TRUE && exitCode != STILL_ACTIVE)
       
   501 		{
       
   502 			// TCFServer is really dead
       
   503 			return FALSE;
       
   504 		}
       
   505 		else
       
   506 		{
       
   507 			// TCFServer is still active
       
   508 			return TRUE;
       
   509 		}
       
   510 	}
       
   511 	else
       
   512 	{
       
   513 		// TCFServer is really dead
       
   514 		return FALSE;
       
   515 	}
       
   516 }
   492 long CClientManager::StopServer()
   517 long CClientManager::StopServer()
   493 {
   518 {
   494 	long ret = TCAPI_ERR_NONE;
   519 	long ret = TCAPI_ERR_NONE;
   495 	pServerProcessData pData = m_Server->GetProcessPtr();
   520 	pServerProcessData pData = m_Server->GetProcessPtr();
   496 
   521 
   514 	else
   539 	else
   515 	{
   540 	{
   516 		// substract ref count
   541 		// substract ref count
   517 		pData->numRefs--;
   542 		pData->numRefs--;
   518 		if (pData->numRefs < 0) pData->numRefs = 0;
   543 		if (pData->numRefs < 0) pData->numRefs = 0;
       
   544 
       
   545 		bool sendStop = true;
       
   546 		if (!IsTCFServerActive(pData->serverProcess.dwProcessId))
       
   547 		{
       
   548 			sendStop = false;
       
   549 			pData->numRefs = 0;
       
   550 		}
       
   551 
   519 		// if refcount == 0 then really stop the server process
   552 		// if refcount == 0 then really stop the server process
   520 		if (pData->numRefs == 0)
   553 		if (pData->numRefs == 0)
   521 		{
   554 		{
   522 			// last client process is closing
   555 			if (sendStop)
   523 			// tell server to exit
   556 			{
   524 			ServerCommandData cmdrsp;
   557 				// last client process is closing
   525 			cmdrsp.command = eCmdExit;
   558 				// tell server to exit
   526 			
   559 				ServerCommandData cmdrsp;
   527 			TCDEBUGLOGS(" SendCommand eCmdExit\n");
   560 				cmdrsp.command = eCmdExit;
   528 			m_Server->SendCommand(&cmdrsp);
   561 				
   529 			TCDEBUGLOGS(" GetResponse eExit\n");
   562 				TCDEBUGLOGS(" SendCommand eCmdExit\n");
   530 			m_Server->GetResponse(&cmdrsp);
   563 				m_Server->SendCommand(&cmdrsp);
   531 			
   564 				TCDEBUGLOGS(" GetResponse eExit\n");
   532 			// wait for process to exit
   565 				m_Server->GetResponse(&cmdrsp);
   533 			TCDEBUGLOGS(" WaitForSingleObject start\n");
   566 				
   534 			DWORD waitErr = ::WaitForSingleObject(m_hServer, 10000L /*INFINITE*/);
   567 				// wait for process to exit
   535 			TCDEBUGLOGA1("CClientManager::StopServer WaitForSingleObject = %d\n", waitErr);
   568 				TCDEBUGLOGS(" WaitForSingleObject start\n");
       
   569 				DWORD waitErr = ::WaitForSingleObject(m_hServer, 10000L /*INFINITE*/);
       
   570 				TCDEBUGLOGA1("CClientManager::StopServer WaitForSingleObject = %d\n", waitErr);
       
   571 			}
   536 
   572 
   537 			// now close our handle to server process
   573 			// now close our handle to server process
   538 			if (m_hServer != NULL)
   574 			if (m_hServer != NULL)
   539 			{
   575 			{
   540 				CloseHandle(m_hServer);
   576 				CloseHandle(m_hServer);
   578 }
   614 }
   579 
   615 
   580 BOOL CClientManager::IsServerRunning()
   616 BOOL CClientManager::IsServerRunning()
   581 {
   617 {
   582 	pServerProcessData pData = m_Server->GetProcessPtr();
   618 	pServerProcessData pData = m_Server->GetProcessPtr();
   583 	if (pData->serverProcess.hProcess != NULL)
   619 	if (IsTCFServerActive(pData->serverProcess.dwProcessId))
       
   620 	{
   584 		return TRUE;
   621 		return TRUE;
       
   622 	}
   585 	else
   623 	else
       
   624 	{
   586 		return FALSE;
   625 		return FALSE;
   587 
   626 	}
   588 }
   627 }
   589 
   628 
   590 void CClientManager::CreateLockFile(DWORD processId)
   629 void CClientManager::CreateLockFile(DWORD processId)
   591 {
   630 {
   592 	if (m_ServerLockFile != NULL)
   631 	if (m_ServerLockFile != NULL)
   638 	}
   677 	}
   639 }
   678 }
   640 
   679 
   641 void CClientManager::DeleteFromLockFile(DWORD serverProcessId)
   680 void CClientManager::DeleteFromLockFile(DWORD serverProcessId)
   642 {
   681 {
   643 	DWORD callingId[10];
   682 	DWORD creatorIds[10];
   644 	DWORD serverId[10];
   683 	DWORD serverIds[10];
   645 	int numIds = 0;
   684 	int numIds = 0;
   646 
   685 
   647 	DWORD ourProcessId = ::GetCurrentProcessId();
   686 	DWORD ourProcessId = ::GetCurrentProcessId();
   648 
   687 
   649 	if (m_ServerLockFile != NULL)
   688 	if (m_ServerLockFile != NULL)
   661 			if (f)
   700 			if (f)
   662 			{
   701 			{
   663 				BOOL done = FALSE;
   702 				BOOL done = FALSE;
   664 				while (!done)
   703 				while (!done)
   665 				{
   704 				{
   666 					DWORD cId = 0xffffffff;
   705 					DWORD creatorId = 0xffffffff;
   667 					DWORD sId = 0xffffffff;
   706 					DWORD serverId = 0xffffffff;
   668 					int n = fscanf(f, "%ld %ld\n", &cId, &sId);
   707 					int n = fscanf(f, "%ld %ld\n", &creatorId, &serverId);
   669 					if (n == 2)
   708 					if (n == 2)
   670 					{
   709 					{
   671 						TCDEBUGLOGA3("CClientManager::DeleteFromLockFile numIds=%d sId=%d pId=%d\n", numIds, cId, sId);
   710 						TCDEBUGLOGA3("CClientManager::DeleteFromLockFile numIds=%d creatorId=%d serverId=%d\n", numIds, creatorId, serverId);
   672 						if (cId != ourProcessId || sId != serverProcessId)
   711 						if (creatorId != ourProcessId || serverId != serverProcessId)
   673 						{
   712 						{
   674 							callingId[numIds] = cId;
   713 							creatorIds[numIds] = creatorId;
   675 							serverId[numIds] = sId;
   714 							serverIds[numIds] = serverId;
   676 							numIds++;
   715 							numIds++;
   677 							if (numIds > 9)
   716 							if (numIds > 9)
   678 								done = TRUE;
   717 								done = TRUE;
   679 						}
   718 						}
   680 					}
   719 					}
   693 				f = fopen(m_ServerLockFile, "wt");
   732 				f = fopen(m_ServerLockFile, "wt");
   694 				if (f)
   733 				if (f)
   695 				{
   734 				{
   696 					for (int i = 0; i < numIds; i++)
   735 					for (int i = 0; i < numIds; i++)
   697 					{
   736 					{
   698 						fprintf(f, "%ld %ld\n", callingId[i], serverId[i]);
   737 						fprintf(f, "%ld %ld\n", creatorIds[i], serverIds[i]);
   699 					}
   738 					}
   700 					fclose(f);
   739 					fclose(f);
   701 				}
   740 				}
   702 			}
   741 			}
   703 		}
   742 		}
   706 
   745 
   707 // Currently assumes there is only ONE TCFServer, but multiple client processes (that use that server)
   746 // Currently assumes there is only ONE TCFServer, but multiple client processes (that use that server)
   708 // we should not have more than a few Carbide processes connecting to the same TCFServer
   747 // we should not have more than a few Carbide processes connecting to the same TCFServer
   709 void CClientManager::TerminateServerThroughLockFile(pServerProcessData pData)
   748 void CClientManager::TerminateServerThroughLockFile(pServerProcessData pData)
   710 {
   749 {
   711 	DWORD callingId[10];
   750 	DWORD creatorIds[10];
   712 	DWORD serverId[10];
   751 	DWORD serverIds[10];
   713 	BOOL liveCaller[10];
   752 	BOOL liveCaller[10];
   714 	int numIds = 0;
   753 	int numIds = 0;
   715 	if (m_ServerLockFile != NULL)
   754 	if (m_ServerLockFile != NULL)
   716 	{
   755 	{
   717 		DWORD attr = ::GetFileAttributes(m_ServerLockFile);
   756 		DWORD attr = ::GetFileAttributes(m_ServerLockFile);
   727 			if (f)
   766 			if (f)
   728 			{
   767 			{
   729 				BOOL done = FALSE;
   768 				BOOL done = FALSE;
   730 				while (!done)
   769 				while (!done)
   731 				{
   770 				{
   732 					DWORD cId = 0xffffffff;
   771 					DWORD creatorId = 0xffffffff;
   733 					DWORD sId = 0xffffffff;
   772 					DWORD serverId = 0xffffffff;
   734 					int n = fscanf(f, "%ld %ld\n", &cId, &sId);
   773 					int n = fscanf(f, "%ld %ld\n", &creatorId, &serverId);
   735 					if (n == 2)
   774 					if (n == 2)
   736 					{
   775 					{
   737 						TCDEBUGLOGA3("CClientManager::TerminateServerThroughLockFile n=%d sId=%d pId=%d\n", n, cId, sId);
   776 						TCDEBUGLOGA3("CClientManager::TerminateServerThroughLockFile n=%d creatorId=%d serverId=%d\n", n, creatorId, serverId);
   738 						callingId[numIds] = cId;
   777 						creatorIds[numIds] = creatorId;
   739 						serverId[numIds] = sId;
   778 						serverIds[numIds] = serverId;
   740 						numIds++;
   779 						numIds++;
   741 						if (numIds > 9)
   780 						if (numIds > 9)
   742 							done = TRUE;
   781 							done = TRUE;
   743 					}
   782 					}
   744 					else
   783 					else
   749 				fclose(f);
   788 				fclose(f);
   750 
   789 
   751 				int numDeadCallers = 0;
   790 				int numDeadCallers = 0;
   752 				for (int i = 0; i < numIds; i++)
   791 				for (int i = 0; i < numIds; i++)
   753 				{
   792 				{
   754 					HANDLE h = ::OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, callingId[i]);
   793 					HANDLE h = ::OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, creatorIds[i]);
   755 					if (h)
   794 					if (h)
   756 					{
   795 					{
   757 						// calling process is still alive
   796 						// calling process is still alive
   758 						liveCaller[i] = TRUE;
   797 						liveCaller[i] = TRUE;
       
   798 						DWORD exitCode = -5;
       
   799 						BOOL exitCall = ::GetExitCodeProcess(h, &exitCode);
       
   800 						DWORD id = ::GetCurrentProcessId();
   759 						::CloseHandle(h);
   801 						::CloseHandle(h);
   760 						TCDEBUGLOGA1("CClientManager::TerminateServerThroughLockFile %d alive\n", callingId[i]);
   802 						TCDEBUGLOGA3("CClientManager::TerminateServerThroughLockFile %d alive exitCall=%d currentId=%d\n", creatorIds[i], exitCall, id);
       
   803 						if (exitCall == TRUE && exitCode != STILL_ACTIVE)
       
   804 						{
       
   805 							liveCaller[i] = FALSE;
       
   806 							numDeadCallers++;
       
   807 						}
       
   808 						{
       
   809 							TCDEBUGLOGA2("CClientManager::TerminateServerThroughLockFile exitCode=%d still_active=%d\n", exitCode, STILL_ACTIVE);
       
   810 						}
   761 					}
   811 					}
   762 					else
   812 					else
   763 					{
   813 					{
   764 						liveCaller[i] = FALSE;
   814 						liveCaller[i] = FALSE;
   765 						numDeadCallers++;
   815 						numDeadCallers++;
   766 						DWORD err = ::GetLastError();
   816 						DWORD err = ::GetLastError();
   767 						TCDEBUGLOGA3("CClientManager::TerminateServerThroughLockFile %d dead err=%d:%s\n", callingId[i], err, GetErrorText(err));
   817 						TCDEBUGLOGA3("CClientManager::TerminateServerThroughLockFile %d dead err=%d:%s\n", creatorIds[i], err, GetErrorText(err));
   768 					}
   818 					}
   769 				}
   819 				}
   770 				if (numDeadCallers == numIds)
   820 				if (numDeadCallers == numIds)
   771 				{
   821 				{
       
   822 					// All clients of this TCFServer are dead
   772 					// terminate the TCFServer, and delete lock file
   823 					// terminate the TCFServer, and delete lock file
   773 					pData->numRefs = 0;
   824 					pData->numRefs = 0;
   774 					::remove(m_ServerLockFile);
   825 					::remove(m_ServerLockFile);
   775 					HANDLE h = ::OpenProcess(SYNCHRONIZE|PROCESS_TERMINATE, FALSE, serverId[0]);
   826 					HANDLE h = ::OpenProcess(SYNCHRONIZE|PROCESS_TERMINATE, FALSE, serverIds[0]);
   776 					if (h)
   827 					if (h)
   777 					{
   828 					{
   778 						BOOL ret = ::TerminateProcess(h, -1);
   829 						BOOL ret = ::TerminateProcess(h, -1);
   779 						if (ret == 0)
   830 						if (ret == 0)
   780 						{
   831 						{
   784 						::CloseHandle(h);
   835 						::CloseHandle(h);
   785 					}
   836 					}
   786 				}
   837 				}
   787 				else
   838 				else
   788 				{
   839 				{
   789 					// leave TCFServer running, recreate lock file and save live callers
   840 					// some java clients are still alive
   790 					::remove(m_ServerLockFile);
   841 					//   check to see if TCFServer is still alive
   791 					f = fopen(m_ServerLockFile, "wt");
   842 					if (IsTCFServerActive(serverIds[0]))
   792 					if (f)
       
   793 					{
   843 					{
   794 						for (int i = 0; i < numIds; i++)
   844 						// TCFServer is still active
       
   845 						// leave TCFServer running, recreate lock file and save live callers
       
   846 						::remove(m_ServerLockFile);
       
   847 						f = fopen(m_ServerLockFile, "wt");
       
   848 						if (f)
   795 						{
   849 						{
   796 							if (liveCaller[i])
   850 							for (int i = 0; i < numIds; i++)
   797 							{
   851 							{
   798 								fprintf(f, "%ld %ld\n", callingId[i], serverId[i]);
   852 								if (liveCaller[i])
       
   853 								{
       
   854 									fprintf(f, "%ld %ld\n", creatorIds[i], serverIds[i]);
       
   855 								}
   799 							}
   856 							}
       
   857 							fclose(f);
   800 						}
   858 						}
   801 						fclose(f);
   859 						pData->numRefs -= numDeadCallers;
       
   860 						if (pData->numRefs < 0) pData->numRefs = 0;
   802 					}
   861 					}
   803 					pData->numRefs -= numDeadCallers;
   862 					else
   804 					if (pData->numRefs < 0) pData->numRefs = 0;
   863 					{
       
   864 						// TCFServer is really dead
       
   865 						pData->numRefs = 0;
       
   866 						::remove(m_ServerLockFile);
       
   867 					}
   805 				}
   868 				}
   806 			}
   869 			}
   807 			else
   870 			else
   808 			{
   871 			{
   809 				// error opening lock file
   872 				// error opening lock file
       
   873 				// perhaps the user deleted it,
       
   874 				//   if so, we assume he has also deleted the TCFServer as we now have no way of verifying if the 
       
   875 				//   process is dead.
       
   876 				pData->numRefs = 0;
   810 				DWORD err = ::GetLastError();
   877 				DWORD err = ::GetLastError();
   811 				TCDEBUGLOGA2("CClientManager::TerminateServerThroughLockFile fopenErr=%d:%s\n", err, GetErrorText(err));
   878 				TCDEBUGLOGA2("CClientManager::TerminateServerThroughLockFile fopenErr=%d:%s\n", err, GetErrorText(err));
   812 			}
   879 			}
   813 		}
   880 		}
   814 	}
   881 	}