in sfwrapper/inc/h_fabric_macro_generator.h [214:299]
HRESULT H_FABRIC_API(IFABRIC_METHOD_NAME)(H_FABRIC_HANDLE(IFABRIC_INTERFACE_NAME) handle \
ARGS_C_DECLARATION(in_args) \
) \
{ \
HRESULT hr; /*also used a result*/ \
/*Codes_SRS_H_FABRIC_MACRO_GENERATOR_02_007: [ If handle is NULL then H_FABRIC_API(IFABRIC_METHOD_NAME) shall fail and return NULL. ]*/ \
if (handle == NULL) \
{ \
LogError("invalid " MU_TOSTRING(HANDLE_TYPE) " handle=%p", handle); \
hr = E_POINTER; \
} \
else \
{ \
/*Codes_SRS_H_FABRIC_MACRO_GENERATOR_02_008: [ H_FABRIC_API(IFABRIC_METHOD_NAME) shall record the start time of the request by calling timer_global_get_elapsed_ms. ]*/ \
double startTime = timer_global_get_elapsed_ms(); /*time spend here cannot exceed timeoutMilliseconds*/ \
double elapsed; \
uint32_t retries = 0; /*incremented at every API call - 0 means "it will call once", "1" means it will call 2 times". It is in the name: **re**tries.*/ \
\
do \
{ \
/*Codes_SRS_H_FABRIC_MACRO_GENERATOR_02_009: [ H_FABRIC_API(IFABRIC_METHOD_NAME) shall call IFABRIC_METHOD_NAME on the instance of IFABRIC_INTERFACE_NAME. ]*/ \
hr = IFABRIC_METHOD_NAME(handle->This ARGS_C_CALL(in_args)); \
if (FAILED(hr)) \
{ \
LogHRESULTError(hr, "failure in " MU_TOSTRING(IFABRIC_METHOD_NAME) "(handle->This=%p, ...)", \
handle->This); \
\
/*Codes_SRS_H_FABRIC_MACRO_GENERATOR_02_011: [ If the result is FABRIC_E_OBJECT_CLOSED, FABRIC_E_GATEWAY_NOT_REACHABLE, FABRIC_E_TIMEOUT or E_ABORT then H_FABRIC_API(IFABRIC_METHOD_NAME) shall create a new instance of IFABRIC_INTERFACE_NAME. ]*/ \
/* FABRIC_E_TIMEOUT was observed in certain cases, such as RestartPartition. We should retry by creating a new client and trying the call again, */ \
/* up to the timeout specified in the H_FABRIC_HANDLE. */ \
if ((hr == E_ABORT) || (hr == FABRIC_E_OBJECT_CLOSED) || (hr == FABRIC_E_GATEWAY_NOT_REACHABLE) || (hr == FABRIC_E_TIMEOUT)) \
{ \
IFABRIC_INTERFACE_NAME* newInstance = NULL; \
\
HRESULT hr_create; \
hr_create = CREATE_IFABRICINSTANCE_NAME(IFABRIC_INTERFACE_NAME)(&newInstance); \
if (FAILED(hr_create)) \
{ \
/*Codes_SRS_H_FABRIC_MACRO_GENERATOR_02_012: [ If creating the new instance of IFABRIC_INTERFACE_NAME fails then H_FABRIC_API(IFABRIC_METHOD_NAME) shall retry using the existing IFABRIC_INTERFACE_NAME. ]*/ \
LogHRESULTError(hr_create, "failure in CREATE_IFABRICINSTANCE_NAME(" MU_TOSTRING(IFABRIC_INTERFACE_NAME) ")(&newInstance=%p)", &newInstance); \
/*keep retrying until timeout*/ \
} \
else \
{ \
/*Codes_SRS_H_FABRIC_MACRO_GENERATOR_02_013: [ Otherwise H_FABRIC_API(IFABRIC_METHOD_NAME) shall release the existing instance and shall retry using new newly created IFABRIC_INTERFACE_NAME. ]*/ \
/*let go of the old instance*/ \
(void)handle->This->lpVtbl->Release(handle->This); \
\
/*replace it with the new instance*/ \
handle->This = newInstance; \
} \
} \
else if (0 RESULTS_CHECK(permanent_failures)) \
{ \
/*Codes_SRS_H_FABRIC_MACRO_GENERATOR_42_001: [ If the result is any value from permanent_failures then H_FABRIC_API(IFABRIC_METHOD_NAME) shall return. ]*/ \
break; \
} \
else \
{ \
/*Codes_SRS_H_FABRIC_MACRO_GENERATOR_02_014: [ If the result is any other value except FABRIC_E_OBJECT_CLOSED, FABRIC_E_GATEWAY_NOT_REACHABLE or E_ABORT then H_FABRIC_API(IFABRIC_METHOD_NAME) shall retry. ]*/ \
/*some other HRESULT, so retry without re-creating the object*/ \
} \
} \
else \
{ \
/*Codes_SRS_H_FABRIC_MACRO_GENERATOR_02_010: [ If the call succeeds then H_FABRIC_API(IFABRIC_METHOD_NAME) shall succeed and return. ]*/ \
break; \
} \
\
/*Codes_SRS_H_FABRIC_MACRO_GENERATOR_02_015: [ H_FABRIC_API(IFABRIC_METHOD_NAME) shall sleep msBetweenRetries. ]*/ \
ThreadAPI_Sleep(handle->msBetweenRetries); \
retries++; \
elapsed = timer_global_get_elapsed_ms() - startTime; \
\
/*Codes_SRS_H_FABRIC_MACRO_GENERATOR_02_016: [ If the total time spend retrying exceeds timeoutMilliseconds then H_FABRIC_API(IFABRIC_METHOD_NAME) shall return the last error code. ]*/ \
/*Codes_SRS_H_FABRIC_MACRO_GENERATOR_02_017: [ If the total number of retries exceeds nMaxRetries then H_FABRIC_API(IFABRIC_METHOD_NAME) shall return the last error code. ]*/ \
} while ((retries < handle->nMaxRetries) && (elapsed < timeoutMilliseconds)); \
\
if(FAILED(hr)) \
{ \
LogHRESULTError(hr, "tried for %" PRIu32 " times in %" PRIu32 "[ms] and it failed", retries, timeoutMilliseconds); \
} \
} \
\
return hr; \
}