HRESULT MU_C4()

in inc/sf_c_util/fabric_async_op_wrapper.h [140:251]


    HRESULT MU_C4(interface_name, _, operation_name, _execute_async)(interface_name* com_object BS2SF_ASYNC_OP_EXTRACT_BEGIN_ARGS(__VA_ARGS__), MU_C4(interface_name, _, operation_name, _COMPLETE_CB) on_complete, void* on_complete_context) \
    { \
        /* Codes_SRS_FABRIC_ASYNC_OP_WRAPPER_01_005: [ on_complete_context shall be allowed to be NULL. ]*/ \
        HRESULT result; \
        if ( \
            /* Codes_SRS_FABRIC_ASYNC_OP_WRAPPER_01_003: [ If com_object is NULL, _execute_async shall fail and return E_INVALIDARG. ]*/ \
            (com_object == NULL) || \
            /* Codes_SRS_FABRIC_ASYNC_OP_WRAPPER_01_004: [ If on_complete is NULL, _execute_async shall fail and return E_INVALIDARG. ]*/ \
            (on_complete == NULL) \
           ) \
        { \
            LogError("Invalid arguments: interface_name* com_object=%p, ..., " MU_TOSTRING(MU_C4(interface_name, _, operation_name, _COMPLETE_CB)) " on_complete=%p, void* on_complete_context=%p", com_object, on_complete, on_complete_context); \
            result = E_INVALIDARG; \
        } \
        else \
        { \
            bool callback_expected = false; \
            /* Codes_SRS_FABRIC_ASYNC_OP_WRAPPER_01_006: [ _execute_async shall allocate a context used to store on_complete and on_complete_context. ]*/ \
            MU_C4(interface_name, _, operation_name, _CONTEXT)* fabric_async_operation_wrapper_context = (MU_C4(interface_name, _, operation_name, _CONTEXT)*)malloc(sizeof(MU_C4(interface_name, _, operation_name, _CONTEXT))); \
            if (fabric_async_operation_wrapper_context == NULL) \
            { \
                /* Codes_SRS_FABRIC_ASYNC_OP_WRAPPER_01_016: [ If any other error occurs, _execute_async shall fail and return E_FAIL. ]*/ \
                LogError("malloc failed for size %zu", sizeof(MU_C4(interface_name, _, operation_name, _CONTEXT))); \
                result = E_FAIL; \
            } \
            else \
            { \
                /* Codes_SRS_FABRIC_ASYNC_OP_WRAPPER_01_027: [ _execute_async shall increment the reference count for com_object. ]*/ \
                (void)com_object->lpVtbl->AddRef(com_object); \
                { \
                    fabric_async_operation_wrapper_context->com_object = com_object; \
                    fabric_async_operation_wrapper_context->on_complete = on_complete; \
                    fabric_async_operation_wrapper_context->on_complete_context = on_complete_context; \
                    IFabricAsyncOperationContext* fabric_operation_context; \
                    /* Codes_SRS_FABRIC_ASYNC_OP_WRAPPER_01_007: [ _execute_async shall create a async operation callback object by calling fabric_async_op_cb_create, passing as arguments the wrapper complete callback and the context with on_complete and on_complete_context. ]*/ \
                    FABRIC_ASYNC_OP_CB_HANDLE fabric_async_op_cb = fabric_async_op_cb_create(MU_C4(interface_name, _, operation_name, wrapper_cb), fabric_async_operation_wrapper_context); \
                    if (fabric_async_op_cb == NULL) \
                    { \
                        /* Codes_SRS_FABRIC_ASYNC_OP_WRAPPER_01_016: [ If any other error occurs, _execute_async shall fail and return E_FAIL. ]*/ \
                        LogError("fabric_async_op_cb_create failed"); \
                        result = E_FAIL; \
                    } \
                    else \
                    { \
                        /* Codes_SRS_FABRIC_ASYNC_OP_WRAPPER_01_008: [ A COM wrapper shall be created for the async operation callback object. ]*/ \
                        IFabricAsyncOperationCallback* callback = COM_WRAPPER_CREATE(FABRIC_ASYNC_OP_CB_HANDLE, IFabricAsyncOperationCallback, fabric_async_op_cb, fabric_async_op_cb_destroy); \
                        if (callback == NULL) \
                        { \
                            /* Codes_SRS_FABRIC_ASYNC_OP_WRAPPER_01_016: [ If any other error occurs, _execute_async shall fail and return E_FAIL. ]*/ \
                            LogError("COM wrapper object creation failed"); \
                            fabric_async_op_cb_destroy(fabric_async_op_cb); \
                            result = E_FAIL; \
                        } \
                        else \
                        { \
                            /* Codes_SRS_FABRIC_ASYNC_OP_WRAPPER_01_009: [ _execute_async shall call Begin{operation_name} on com_object, passing as arguments the begin arguments and the async operation callback COM object. ]*/ \
                            result = com_object->lpVtbl->MU_C2(Begin, operation_name)(com_object BS2SF_ASYNC_OP_EXTRACT_BEGIN_ARG_VALUES(__VA_ARGS__), callback, &fabric_operation_context); \
                            if (FAILED(result)) \
                            { \
                                /* Codes_SRS_FABRIC_ASYNC_OP_WRAPPER_01_014: [ If Begin{operation_name} fails, _execute_async shall return the error returned by Begin{operation_name}. ]*/ \
                                LogHRESULTError(result, "com_object->lpVtbl->Begin" MU_TOSTRING(operation_name) " failed."); \
                                /* return result as is */ \
                            } \
                            else \
                            { \
                                /* Codes_SRS_FABRIC_ASYNC_OP_WRAPPER_01_010: [ If fabric_operation_context has completed synchronously: ]*/ \
                                if (fabric_operation_context->lpVtbl->CompletedSynchronously(fabric_operation_context)) \
                                { \
                                    /* Codes_SRS_FABRIC_ASYNC_OP_WRAPPER_01_011: [ _execute_async shall call End{operation_name} on com_object. ]*/ \
                                    BS2SF_ASYNC_OP_EXTRACT_VARS_FOR_END_ARGS(__VA_ARGS__) \
                                    result = com_object->lpVtbl->MU_C2(End, operation_name)(com_object, fabric_operation_context BS2SF_ASYNC_OP_EXTRACT_ADDRESS_END_ARG_VALUES(__VA_ARGS__)); \
                                    if (FAILED(result)) \
                                    { \
                                        /* Codes_SRS_FABRIC_ASYNC_OP_WRAPPER_01_015: [ If End{operation_name} fails, _execute_async shall return the error returned by End{operation_name}. ]*/ \
                                        LogHRESULTError(result, MU_TOSTRING(MU_C2(End, operation_name)) " failed"); \
                                        /* return result as is */ \
                                    } \
                                    else \
                                    { \
                                        /* Codes_SRS_FABRIC_ASYNC_OP_WRAPPER_01_012: [ _execute_async shall call the on_complete and pass as arguments on_complete_context, S_OK and the end argument values obtained from End{operation_name}. ]*/ \
                                        on_complete(on_complete_context, S_OK BS2SF_ASYNC_OP_EXTRACT_END_ARG_VALUES(__VA_ARGS__)); \
                                        /* Codes_SRS_FABRIC_ASYNC_OP_WRAPPER_01_026: [ On success, _execute_async shall return S_OK. ]*/ \
                                        result = S_OK; \
                                    } \
                                } \
                                else \
                                { \
                                    callback_expected = true; \
                                    /* Codes_SRS_FABRIC_ASYNC_OP_WRAPPER_01_026: [ On success, _execute_async shall return S_OK. ]*/ \
                                    result = S_OK; \
                                } \
                                /* Codes_SRS_FABRIC_ASYNC_OP_WRAPPER_01_013: [ _execute_async shall release the asynchronous operation context obtained from Begin{operation_name}. ]*/ \
                                (void)fabric_operation_context->lpVtbl->Release(fabric_operation_context); \
                            } \
                            (void)callback->lpVtbl->Release(callback); \
                        } \
                    } \
                    if (!callback_expected) \
                    { \
                        /* Codes_SRS_FABRIC_ASYNC_OP_WRAPPER_01_028: [ _execute_async shall decrement the reference count for com_object. ]*/ \
                        (void)com_object->lpVtbl->Release(com_object); \
                    } \
                } \
                if (!callback_expected) \
                { \
                    /* Codes_SRS_FABRIC_ASYNC_OP_WRAPPER_01_029: [ _execute_async shall free the context used to store on_complete and on_complete_context. ]*/ \
                    free(fabric_async_operation_wrapper_context); \
                } \
            } \
        } \
        return result; \
    }