sf-c-util/devdoc/fabric_async_op_wrapper_req...

117 строки
6.2 KiB
Markdown

`fabric_async_op_wrapper` requirements
================
## Overview
`fabric_async_op_wrapper` is a module that implements a wrapper over the Begin/End APIs that are part of a Fabric asynchronous operation.
## Exposed API
```c
#define DECLARE_FABRIC_ASYNC_OPERATION(interface_name, operation_name, ...) \
...
#define DEFINE_FABRIC_ASYNC_OPERATION(interface_name, operation_name, ...) \
...
```
### DECLARE_FABRIC_ASYNC_OPERATION
```c
#define DECLARE_FABRIC_ASYNC_OPERATION(interface_name, operation_name, ...)
```
`DECLARE_FABRIC_ASYNC_OPERATION` expands to code declaring a wrapper function that executes the asynchronous operation and the associated completion callback.
`...` is made of:
- `BEGIN_ARGS(...)`, which is a list of tuples containing the argument type and name for each of the begin arguments.
- `END_ARGS(...)`, which is a list of tuples containing the argument type and name for each of the end arguments.
**SRS_FABRIC_ASYNC_OP_WRAPPER_01_001: [** `DECLARE_FABRIC_ASYNC_OPERATION` shall declare a function with the following prototype: **]**
```c
HRESULT {interface_name}_{operation_name}_execute_async(interface_name* com_object, {begin_args}, {interface_name}_{operation_name}_COMPLETE_CB on_complete, void* on_complete_context);
```
**SRS_FABRIC_ASYNC_OP_WRAPPER_01_002: [** `DECLARE_FABRIC_ASYNC_OPERATION` shall declare the async operation completion callback with the prototype: **]**
```c
typedef void {interface_name}_{operation_name}_COMPLETE_CB(void* context, HRESULT async_operation_result, {end_args});
```
### DEFINE_FABRIC_ASYNC_OPERATION
```c
#define DEFINE_FABRIC_ASYNC_OPERATION(interface_name, operation_name, ...)
```
`DEFINE_FABRIC_ASYNC_OPERATION` expands to code implementing a wrapper function that executes the asynchronous operation and the associated completion callback.
**SRS_FABRIC_ASYNC_OP_WRAPPER_01_025: [** `DEFINE_FABRIC_ASYNC_OPERATION` shall implement a function with the following prototype: **]**
```c
HRESULT {interface_name}_{operation_name}_execute_async(interface_name* com_object, {begin_args}, {interface_name}_{operation_name}_COMPLETE_CB on_complete, void* on_complete_context);
```
**SRS_FABRIC_ASYNC_OP_WRAPPER_01_003: [** If `com_object` is NULL, `_execute_async` shall fail and return `E_INVALIDARG`. **]**
**SRS_FABRIC_ASYNC_OP_WRAPPER_01_004: [** If `on_complete` is NULL, `_execute_async` shall fail and return `E_INVALIDARG`. **]**
**SRS_FABRIC_ASYNC_OP_WRAPPER_01_005: [** `on_complete_context` shall be allowed to be `NULL`. **]**
**SRS_FABRIC_ASYNC_OP_WRAPPER_01_006: [** `_execute_async` shall allocate a context used to store `on_complete` and `on_complete_context`. **]**
**SRS_FABRIC_ASYNC_OP_WRAPPER_01_027: [** `_execute_async` shall increment the reference count for `com_object`. **]**
**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`. **]**
**SRS_FABRIC_ASYNC_OP_WRAPPER_01_008: [** A COM wrapper shall be created for the async operation callback object. **]**
**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. **]**
**SRS_FABRIC_ASYNC_OP_WRAPPER_01_010: [** If `fabric_operation_context` has completed synchronously: **]**
- **SRS_FABRIC_ASYNC_OP_WRAPPER_01_011: [** `_execute_async` shall call `End{operation_name}` on `com_object`. **]**
- **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}`. **]**
- **SRS_FABRIC_ASYNC_OP_WRAPPER_01_028: [** `_execute_async` shall decrement the reference count for `com_object`. **]**
- **SRS_FABRIC_ASYNC_OP_WRAPPER_01_029: [** `_execute_async` shall free the context used to store `on_complete` and `on_complete_context`. **]**
**SRS_FABRIC_ASYNC_OP_WRAPPER_01_013: [** `_execute_async` shall release the asynchronous operation context obtained from `Begin{operation_name}`. **]**
**SRS_FABRIC_ASYNC_OP_WRAPPER_01_026: [** On success, `_execute_async` shall return `S_OK`. **]**
**SRS_FABRIC_ASYNC_OP_WRAPPER_01_014: [** If `Begin{operation_name}` fails, `_execute_async` shall return the error returned by `Begin{operation_name}`. **]**
**SRS_FABRIC_ASYNC_OP_WRAPPER_01_015: [** If `End{operation_name}` fails, `_execute_async` shall return the error returned by `End{operation_name}`. **]**
**SRS_FABRIC_ASYNC_OP_WRAPPER_01_016: [** If any other error occurs, `_execute_async` shall fail and return `E_FAIL`. **]**
**SRS_FABRIC_ASYNC_OP_WRAPPER_01_017: [** `DEFINE_FABRIC_ASYNC_OPERATION` shall define the wrapper completion callback: **]**
```c
static void {interface_name}_{operation_name}_wrapper_cb(void* context, IFabricAsyncOperationContext* fabric_async_operation_context);
```
**SRS_FABRIC_ASYNC_OP_WRAPPER_01_018: [** If `context` is `NULL`, `_wrapper_cb` shall return. **]**
**SRS_FABRIC_ASYNC_OP_WRAPPER_01_019: [** Otherwise, `_wrapper_cb` shall check whether the async operation has completed synchronously. **]**
**SRS_FABRIC_ASYNC_OP_WRAPPER_01_020: [** If the async operation has completed synchronously, `_wrapper_cb` shall return. **]**
**SRS_FABRIC_ASYNC_OP_WRAPPER_01_021: [** If the async operation has not completed synchronously: **]**
- **SRS_FABRIC_ASYNC_OP_WRAPPER_01_022: [** `_wrapper_cb` shall call `End{operation_name}` on the `com_object` passed to `_execute_async`. **]**
- **SRS_FABRIC_ASYNC_OP_WRAPPER_01_023: [** `_wrapper_cb` shall call the `on_complete` and pass as arguments `on_complete_context`, `S_OK` and the end argument values obtained from `End{operation_name}`. **]**
- **SRS_FABRIC_ASYNC_OP_WRAPPER_01_030: [** `_wrapper_cb` shall release the com object passed as argument to `_execute_async`. **]**
- **SRS_FABRIC_ASYNC_OP_WRAPPER_01_031: [** `_wrapper_cb` shall free the context created in `_execute_async`. **]**
**SRS_FABRIC_ASYNC_OP_WRAPPER_01_024: [** If the `End{operation_name}` fails, `_wrapper_cb` shall call the `on_complete` and pass as arguments `on_complete_context` and the result of the `End{operation_name}` call. **]**