in common/src/sm.c [379:428]
SM_RESULT sm_exec_begin(SM_HANDLE sm)
{
SM_RESULT result;
/*Codes_SRS_SM_02_021: [ If sm is NULL then sm_exec_begin shall fail and return SM_ERROR. ]*/
if (sm == NULL)
{
LogError("invalid argument SM_HANDLE sm=%p", sm);
result = SM_ERROR;
}
else
{
int32_t state1 = interlocked_add(&sm->state, 0);
if (
/*Codes_SRS_SM_02_054: [ If state is not SM_OPENED then sm_exec_begin shall return SM_EXEC_REFUSED. ]*/
((state1 & SM_STATE_MASK) != SM_OPENED) ||
/*Codes_SRS_SM_02_055: [ If SM_CLOSE_BIT is 1 then sm_exec_begin shall return SM_EXEC_REFUSED. ]*/
((state1 & SM_CLOSE_BIT) == SM_CLOSE_BIT) ||
/*Codes_SRS_SM_42_002: [ If SM_FAULTED_BIT is 1 then sm_exec_begin shall return SM_EXEC_REFUSED. ]*/
((state1 & SM_FAULTED_BIT) == SM_FAULTED_BIT)
)
{
LogError("sm name=%s. cannot call sm_exec_begin when state is %" PRI_SM_STATE "", sm->name, SM_STATE_VALUE(state1));
result = SM_EXEC_REFUSED;
}
else
{
/*Codes_SRS_SM_02_056: [ sm_exec_begin shall increment n. ]*/
(void)interlocked_increment(&sm->non_barrier_call_count);
int32_t state2 = interlocked_add(&sm->state, 0);
/*Codes_SRS_SM_02_057: [ If the state changed after incrementing n then sm_exec_begin shall return SM_EXEC_REFUSED. ]*/
if (state1 != state2)
{
LogError("sm name=%s. state changed meanwhile from %" PRI_SM_STATE " to %" PRI_SM_STATE "", sm->name, SM_STATE_VALUE(state1), SM_STATE_VALUE(state2));
int32_t n = interlocked_decrement(&sm->non_barrier_call_count);
if (n == 0)
{
wake_by_address_single(&sm->non_barrier_call_count);
}
result = SM_EXEC_REFUSED;
}
else
{
/*Codes_SRS_SM_02_058: [ sm_exec_begin shall return SM_EXEC_GRANTED. ]*/
result = SM_EXEC_GRANTED;
}
}
}
return result;
}