보호되는 오퍼레이션을 보호 오퍼레이션이라고 합니다. 보호 오퍼레이션은 상호 배제를 시행해야 할 만큼 충분히 중요한 것으로 간주됩니다. 보호 오브젝트는 하나 이상의 보호 오퍼레이션을 소유하는 오브젝트입니다.
보호 오브젝트를 구현하기 위한 한 가지 방법은 오브젝트에 뮤텍스를 제공하여, 보호되도록 명시적으로 설정된 모든 오퍼레이션이 오퍼레이션 시작 시 뮤텍스를 잠그고 종료 시 해제하도록 하는 것입니다.
보호 오브젝트의 구조에 RiCMonitor 멤버가 추가됩니다. 예를 들면, 다음과 같습니다.
typedef struct A A;
struct A {
RiCMonitor ric_monitor;
/* other members of A */
};
RiCMonitor는 IBM® Rational® Rhapsody® 프레임워크에 정의된 유형 모니터입니다.
ric_monitor 서브오브젝트는 보호되도록 태그가 지정된 오브젝트의 오퍼레이션에 대해서만 사용됩니다. CG::Operation::Concurrency 특성을 사용하여 보호되도록 오퍼레이션에 태그를 지정할 수 있습니다.
보호 오퍼레이션은 보호 책임이 있는 랩퍼 오퍼레이션 내에서 보호됩니다. 보호 오퍼레이션은 다음과 같이 private 오퍼레이션으로 생성됩니다.
예를 들어, B 오브젝트의 보호 오퍼레이션 increase()에 대해 두 개의 함수가 생성됩니다.
랩퍼 오퍼레이션에 대한 선언은 오브젝트에 대한 스펙 파일에서 생성됩니다.
int B_increase(B* const me, int i);
랩퍼 오퍼레이션 increase()는 ric_monitor 오브젝트에 대해 잠금을 얻고 보호 오브젝트를 호출한 후 마지막으로 잠금을 해제합니다.
int B_increase(B* const me, int i) {
int wrapper_return_value;
RIC_OPERATION_LOCK(&me->ric_monitor);
wrapper_return_value = B_increase_guarded(me, i);
RIC_OPERATION_FREE(&me->ric_monitor);
return wrapper_return_value;
}
랩퍼 함수가 잠금을 얻으면, 보호 오퍼레이션은 보호 상태가 되고 잠금이 해제될 때까지 다른 오브젝트의 액세스 없이 해당되는 중요한 오퍼레이션을 수행할 수 있습니다.
static int B_increase_guarded(B* const me, int i) {
{
/*#[ operation increase(int) */
return i++;
/*#]*/
}
}
마찬가지로, 정리를 수행하는 보호 오퍼레이션과 랩퍼 오퍼레이션에 보호 오브젝트에 대한 cleanup 오퍼레이션이 생성됩니다. 예를 들어, 보호 오브젝트 B에 대한 정리는 먼저 B를 잠근 후 실제 정리를 수행하는 cleanup_guarded()를 호출합니다.
void B_Cleanup(B* const me) {
RIC_OPERATION_LOCK(&me->ric_monitor);
B_Cleanup_guarded(me);
}
void B_Cleanup_guarded(B* const me) {
RiCMonitor_cleanup(&me->ric_monitor);
}