static void ASYNC_RETRY_WRAPPER_CALLBACK()

in inc/c_util/async_retry_wrapper.h [463:528]


    static void ASYNC_RETRY_WRAPPER_CALLBACK(async_function_name)(void* context ASYNC_RETRY_WRAPPER_CALLBACK_ARGS_DECLARATION_PROXY(out_args)) \
    { \
        if (context == NULL) \
        { \
            /*Codes_SRS_ASYNC_RETRY_WRAPPER_42_016: [ If context is NULL, on_{async_function_name}_complete shall terminate the process. ]*/ \
            LogCriticalAndTerminate("NULL context for " MU_TOSTRING(async_function_name) " callback"); \
        } \
        else \
        { \
            ASYNC_RETRY_WRAPPER_CONTEXT(async_function_name)* retry_context = context; \
            ASYNC_RETRY_WRAPPER_GET_ENUM_TO_CHECK_PROXY(out_args) \
            if (ASYNC_RETRY_WRAPPER_RETRY_CONDITIONS_PROXY(retry_async_enums)) \
            { \
                /*Codes_SRS_ASYNC_RETRY_WRAPPER_02_003: [ If the out_arg specified as ENUM(type, name, error_value) has one of the values from RETRY_ON_ASYNC(...) and the the time measured from the initial call to ASYNC_RETRY_WRAPPER() exceeded timeout_ms then the user callback specified in ARG_CB(...) shall be called, passing the context from ARG_CONTEXT(...), and the out_args as they were received by this callback handler with the exception of the ENUM(...) which will have the value specified for timeout_error_value. ]*/ \
                bool timed_out = false; \
                if (retry_context->timeout_ms < UINT32_MAX) \
                { \
                    double elapsed_time_ms = timer_global_get_elapsed_ms() - retry_context->start_time; \
                    if (elapsed_time_ms + retry_context->backoff > retry_context->timeout_ms) \
                    { \
                        /*Codes_SRS_ASYNC_RETRY_WRAPPER_42_049: [ Before each retry of the function, If timeout_ms milliseconds have elapsed then {async_function_name}_async_retry_wrapper_with_timeout shall fail and return ASYNC_RETRY_WRAPPER_TIMEOUT. ]*/ \
                        LogError("Retries for " MU_TOSTRING(async_function_name) " timed out after %lf ms (including %" PRIu32 " ms of backoff) (timeout time was %" PRIu32 " ms)", \
                            elapsed_time_ms, retry_context->backoff, retry_context->timeout_ms); \
                            timed_out = true; \
                        /* Codes_SRS_ASYNC_RETRY_WRAPPER_01_001: [ If any error occurs, on_{async_function_name}_complete shall call the user callback specified in ARG_CB(...), passing the context from ARG_CONTEXT(...), and the error_value from all of the ARG(type, name, error_value)'s in out_args. ]*/ \
                        retry_context->user_captured_callback(retry_context->user_captured_callback_context ASYNC_RETRY_WRAPPER_CALLBACK_ARGS_FOR_CALL_WITH_TIMEOUT_PROXY(out_args));\
                        ASYNC_RETRY_WRAPPER_FREE_FIELDS_PROXY(in_args); \
                        /*Codes_SRS_ASYNC_RETRY_WRAPPER_11_001: [ on_{async_function_name}_complete shall assign the threadpool to NULL. ]*/ \
                        THANDLE_ASSIGN(THREADPOOL)(&retry_context->threadpool, NULL); \
                        /*Codes_SRS_ASYNC_RETRY_WRAPPER_42_021: [ on_{async_function_name}_complete shall free the allocated context. ]*/ \
                        free(retry_context); \
                    } \
                } \
                if(!timed_out) \
                { \
                    LogVerbose("Scheduling retry of " MU_TOSTRING(async_function_name)); \
                    /*Codes_SRS_ASYNC_RETRY_WRAPPER_42_017: [ If the out_arg specified as ENUM(type, name, error_value) has one of the values from RETRY_ON(...) then on_{async_function_name}_complete shall call threadpool_schedule_work with {async_function_name}_do_retry as the work_function to retry the asynchronous call and return. ]*/ \
                    if (threadpool_schedule_work(retry_context->threadpool, ASYNC_RETRY_WRAPPER_RETRY_FUNC(async_function_name), retry_context) != 0) \
                    { \
                        LogError("threadpool_schedule_work failed for " MU_TOSTRING(async_function_name)); \
                        /* Codes_SRS_ASYNC_RETRY_WRAPPER_01_001: [ If any error occurs, on_{async_function_name}_complete shall call the user callback specified in ARG_CB(...), passing the context from ARG_CONTEXT(...), and the error_value from all of the ARG(type, name, error_value)'s in out_args. ]*/ \
                        retry_context->user_captured_callback(retry_context->user_captured_callback_context ASYNC_RETRY_WRAPPER_CALLBACK_ARGS_FOR_CALL_WITH_ERROR_PROXY(out_args)); \
                        ASYNC_RETRY_WRAPPER_FREE_FIELDS_PROXY(in_args); \
                        /*Codes_SRS_ASYNC_RETRY_WRAPPER_11_001: [ on_{async_function_name}_complete shall assign the threadpool to NULL. ]*/ \
                        THANDLE_ASSIGN(THREADPOOL)(&retry_context->threadpool, NULL); \
                        /*Codes_SRS_ASYNC_RETRY_WRAPPER_42_021: [ on_{async_function_name}_complete shall free the allocated context. ]*/ \
                        free(retry_context); \
                    } \
                    else \
                    { \
                        /* All OK, will execute on threadpool callback */ \
                    } \
                } \
            } \
            else \
            { \
                /*Codes_SRS_ASYNC_RETRY_WRAPPER_42_018: [ on_{async_function_name}_complete shall call the user callback specified in ARG_CB(...), passing the context from ARG_CONTEXT(...), and the out_args as they were received by this callback handler. ]*/ \
                retry_context->user_captured_callback(retry_context->user_captured_callback_context ASYNC_RETRY_WRAPPER_CALLBACK_ARGS_FOR_CALL_PROXY(out_args)); \
                ASYNC_RETRY_WRAPPER_FREE_FIELDS_PROXY(in_args); \
                /*Codes_SRS_ASYNC_RETRY_WRAPPER_11_001: [ on_{async_function_name}_complete shall assign the threadpool to NULL. ]*/ \
                THANDLE_ASSIGN(THREADPOOL)(&retry_context->threadpool, NULL); \
                /*Codes_SRS_ASYNC_RETRY_WRAPPER_42_021: [ on_{async_function_name}_complete shall free the allocated context. ]*/ \
                free(retry_context); \
            } \
        } \
    }