다음을 통해 공유


Out-of-Process 서버 구현 도우미

Out-of-process 서버에서 호출할 수 있는 4개의 도우미 함수를 사용하여 서버 코드 작성 작업을 간소화할 수 있습니다. COM 클라이언트 및 COM in-process 서버는 일반적으로 해당 서버를 호출하지 않습니다. 이러한 함수는 서버에 여러 개의 아파트 또는 여러 클래스 개체가 있는 경우 서버 정품 인증의 경합 상태를 방지하도록 설계되었습니다. 그러나 단일 스레드 및 단일 클래스 개체 서버에 쉽게 사용할 수도 있습니다. 함수는 다음과 같습니다.

제대로 종료하려면 COM 서버가 인스턴스화된 개체 인스턴스 수와 IClassFactory::LockServer 메서드가 호출된 횟수를 추적해야 합니다. 이러한 두 개수가 모두 0에 도달한 경우에만 서버가 종료됩니다. 단일 스레드 COM 서버에서 종료 결정은 메시지 큐에 의해 직렬화된 들어오는 활성화 요청과 조정되었습니다. 서버는 최종 개체 인스턴스에서 릴리스를 받고 종료를 결정하면 더 이상 활성화 요청이 디스패치되기 전에 해당 클래스 개체를 해지합니다. 이 시점 이후에 활성화 요청이 들어오면 COM은 클래스 개체가 해지되었음을 인식하고 SCM(서비스 제어 관리자)에 오류를 반환합니다. 그러면 로컬 서버 프로세스의 새 인스턴스가 실행됩니다.

그러나 서로 다른 클래스 개체가 다른 아파트에 등록되어 있는 아파트 모델 서버와 모든 자유 스레드 서버에서 이 종료 결정은 서버의 한 스레드가 클래스 개체 또는 개체 인스턴스를 전달하는 동안 서버의 한 스레드가 종료되지 않도록 여러 스레드의 활성화 요청과 조정되어야 합니다. 이 문제를 해결하기 위한 클래식적이지만 번거로운 방법 중 하나는 서버가 클래스 개체를 해지한 후 인스턴스 수를 다시 확인하고 모든 인스턴스가 해제될 때까지 활성 상태를 유지하는 것입니다.

서버 작성기가 이러한 유형의 경합 조건을 더 쉽게 처리할 수 있도록 COM은 다음 두 가지 참조 계산 함수를 제공합니다.

전역 프로세스별 참조 수가 0에 도달하면 COM은 CoSuspendClassObjects자동으로 호출하여 새 활성화 요청이 들어오지 않도록 합니다. 그런 다음 서버는 다른 활성화 요청이 들어올 수 있다는 걱정 없이 여가 시간에 다양한 스레드에서 다양한 클래스 개체의 등록을 취소할 수 있습니다. 모든 새 활성화 요청은 이제부터 로컬 서버 프로세스의 새 인스턴스를 시작하는 SCM에 의해 처리됩니다.

로컬 서버 애플리케이션에서 이러한 함수를 사용하는 가장 간단한 방법은 각 인스턴스 개체의 생성자에서 CoAddRefServerProcess 호출하고, fLock 매개 변수가 TRUE 경우 각 IClassFactory::LockServer 메서드에서 호출하는 것입니다. 또한 서버 애플리케이션은 fLock 매개 변수가 FALSE 경우 각 인스턴스 개체의 소멸자 및 각 IClassFactory::LockServer 메서드에서 CoReleaseServerProcess 호출해야 합니다.

마지막으로 서버 애플리케이션은 CoReleaseServerProcess반환 코드에 주의해야 하며 0을 반환하는 경우 서버 애플리케이션은 정리를 시작해야 합니다. 즉, 여러 스레드가 있는 서버의 경우 일반적으로 메시지 루프를 종료하고 CoAddRefServerProcess 호출하고 CoReleaseServerProcess다양한 스레드에 신호를 보내야 합니다. 서버 프로세스 수명 관리 함수를 사용하는 경우 개체 인스턴스와 LockServer 메서드 모두에서 사용해야 합니다. 그렇지 않으면 서버 애플리케이션이 조기에 종료될 수 있습니다.

CoGetClassObject 요청이 수행되면 COM은 서버에 연결하고, 클래스 개체의 IClassFactory 인터페이스를 마샬링하고, 클라이언트 프로세스로 반환하고, IClassFactory 인터페이스를 숨기지 않고, 클라이언트에 반환합니다. 이 시점에서 클라이언트는 일반적으로 TRUE 사용하여 LockServer 호출하여 서버 프로세스가 종료되지 않도록 합니다. 그러나 클래스 개체가 마샬링되는 시점과 클라이언트가 LockServer를 호출할 때와 다른 클라이언트가 동일한 서버에 연결하고, 인스턴스를 가져오고, 해당 인스턴스를 해제할 수 있는 기간 사이에는 서버가 종료되고 연결이 끊긴 IClassFactory 포인터로 첫 번째 클라이언트가 높고 건조하게 됩니다. 이 경합 상태를 방지하기 위해 COM은 IClassFactory 인터페이스를 마샬링할 때 클래스 개체에 TRUELockServer 암시적 호출을 추가하고 클라이언트가 IClassFactory 인터페이스를 해제할 때 FALSE 사용하여 LockServer 암시적 호출을 추가합니다. 따라서 LockServer가 서버에 다시 호출할 필요가 없으며, LockServer 프록시는 실제로 호출을 원격하지 않고 S_OK 반환하기만 하면 됩니다.

Out-of-process 서버 프로세스를 초기화하는 동안 또 다른 활성화 관련 경합 상태가 있습니다. 여러 클래스를 등록하는 COM 서버는 일반적으로 지원하는 각 CLSID에 대한 REGCLS_LOCAL_SERVER CoRegisterClassObject 호출합니다. 모든 클래스에 대해 이 작업을 수행한 후 서버는 메시지 루프를 입력합니다. 단일 스레드 COM 서버의 경우 서버가 메시지 루프에 들어갈 때까지 모든 활성화 요청이 차단됩니다. 그러나 다른 아파트에 다른 클래스 개체를 등록하는 아파트 모델 서버와 모든 무료 스레드 서버의 경우 활성화 요청이 이보다 일찍 도착할 수 있습니다. 아파트 모델 서버의 경우 한 스레드가 메시지 루프를 입력하는 즉시 활성화 요청이 도착할 수 있습니다. 자유 스레드 서버의 경우 첫 번째 클래스 개체가 등록되는 즉시 활성화 요청이 도착할 수 있습니다. 정품 인증은 이 초기에 발생할 수 있으므로 나머지 서버가 초기화를 완료하기 전에 최종 릴리스가 발생할 수도 있습니다(따라서 서버가 종료되기 시작).

이러한 경합 조건을 제거하고 서버 작성기의 작업을 간소화하려면 COM에 여러 클래스 개체를 등록하려는 서버는 REGCLS_LOCAL_SERVER CoRegisterClassObject 호출해야 합니다. 서버에서 지원하는 서로 다른 CLSID 각각에 대한 REGCLS_SUSPENDED. 모든 클래스가 등록되고 서버 프로세스가 들어오는 활성화 요청을 수락할 준비가 되면 서버는 CoResumeClassObjects한 번 호출해야 합니다. 이 함수는 COM에 등록된 모든 클래스에 대해 SCM에 알리도록 지시하고 서버 프로세스에 활성화 요청을 허용하기 시작합니다. 이러한 함수를 사용하면 다음과 같은 이점이 제공됩니다.

  • 등록된 CLSID 수에 관계없이 SCM에 대한 호출이 하나만 이루어지므로 전체 등록 시간(따라서 서버 애플리케이션의 시작 시간)이 줄어듭니다.
  • 서버에 아파트가 여러 개 있고 다른 CLSID가 다른 아파트에 등록되어 있거나 서버가 자유 스레드 서버인 경우 서버가CoResumeClassObjects를 호출할 때까지 활성화 요청이 들어오지 않습니다. 그러면 서버에 모든 CLSID를 등록하고 정품 인증 요청을 처리하고 가능한 종료 요청을 처리하기 전에 제대로 설정할 수 있습니다.

COM 서버 책임