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) |
778 TCDEBUGLOGA3("CClientManager::TerminateServerThroughLockFile %d dead err=%d:%s\n", creatorIds[i], err, GetErrorText(err)); |
817 TCDEBUGLOGA3("CClientManager::TerminateServerThroughLockFile %d dead err=%d:%s\n", creatorIds[i], err, GetErrorText(err)); |
779 } |
818 } |
780 } |
819 } |
781 if (numDeadCallers == numIds) |
820 if (numDeadCallers == numIds) |
782 { |
821 { |
|
822 // All clients of this TCFServer are dead |
783 // terminate the TCFServer, and delete lock file |
823 // terminate the TCFServer, and delete lock file |
784 pData->numRefs = 0; |
824 pData->numRefs = 0; |
785 ::remove(m_ServerLockFile); |
825 ::remove(m_ServerLockFile); |
786 HANDLE h = ::OpenProcess(SYNCHRONIZE|PROCESS_TERMINATE, FALSE, serverIds[0]); |
826 HANDLE h = ::OpenProcess(SYNCHRONIZE|PROCESS_TERMINATE, FALSE, serverIds[0]); |
787 if (h) |
827 if (h) |
795 ::CloseHandle(h); |
835 ::CloseHandle(h); |
796 } |
836 } |
797 } |
837 } |
798 else |
838 else |
799 { |
839 { |
800 // leave TCFServer running, recreate lock file and save live callers |
840 // some java clients are still alive |
801 ::remove(m_ServerLockFile); |
841 // check to see if TCFServer is still alive |
802 f = fopen(m_ServerLockFile, "wt"); |
842 if (IsTCFServerActive(serverIds[0])) |
803 if (f) |
|
804 { |
843 { |
805 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) |
806 { |
849 { |
807 if (liveCaller[i]) |
850 for (int i = 0; i < numIds; i++) |
808 { |
851 { |
809 fprintf(f, "%ld %ld\n", creatorIds[i], serverIds[i]); |
852 if (liveCaller[i]) |
|
853 { |
|
854 fprintf(f, "%ld %ld\n", creatorIds[i], serverIds[i]); |
|
855 } |
810 } |
856 } |
|
857 fclose(f); |
811 } |
858 } |
812 fclose(f); |
859 pData->numRefs -= numDeadCallers; |
|
860 if (pData->numRefs < 0) pData->numRefs = 0; |
813 } |
861 } |
814 pData->numRefs -= numDeadCallers; |
862 else |
815 if (pData->numRefs < 0) pData->numRefs = 0; |
863 { |
|
864 // TCFServer is really dead |
|
865 pData->numRefs = 0; |
|
866 ::remove(m_ServerLockFile); |
|
867 } |
816 } |
868 } |
817 } |
869 } |
818 else |
870 else |
819 { |
871 { |
820 // 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; |
821 DWORD err = ::GetLastError(); |
877 DWORD err = ::GetLastError(); |
822 TCDEBUGLOGA2("CClientManager::TerminateServerThroughLockFile fopenErr=%d:%s\n", err, GetErrorText(err)); |
878 TCDEBUGLOGA2("CClientManager::TerminateServerThroughLockFile fopenErr=%d:%s\n", err, GetErrorText(err)); |
823 } |
879 } |
824 } |
880 } |
825 } |
881 } |