зеркало из https://github.com/Azure/c-pal.git
Specs for threadpool_open move to threadpool_create and threadpool_cl… (#403)
* Specs for threadpool_open move to threadpool_create and threadpool_close to threadpool_dispose * Addressed Dan's comments * Missing SRS_THREADPOOL_WIN32_01_006 added back * Pushing some of the missing changes and some new changes * More changes * One more change remaining * Removed the backtick
This commit is contained in:
Родитель
e1df027dc1
Коммит
6aaa879511
|
@ -56,35 +56,37 @@ MOCKABLE_FUNCTION(, THREADPOOL_HANDLE, threadpool_create, EXECUTION_ENGINE_HANDL
|
|||
|
||||
`threadpool_create` creates a threadpool object that can execute work items.
|
||||
|
||||
**NON_THREADPOOL_01_001: [** `threadpool_create` shall allocate a new threadpool object and on success shall return a non-`NULL` handle. **]**
|
||||
**NON_THREADPOOL_01_001: [** `threadpool_create` shall allocate a new `threadpool` object and on success shall return a non-`NULL` handle. **]**
|
||||
|
||||
**NON_THREADPOOL_01_002: [** If `execution_engine` is `NULL`, `threadpool_create` shall fail and return `NULL`. **]**
|
||||
|
||||
**N_O_N_THREADPOOL_01_011: [** `threadpool_create` shall perform any actions needed to open the `threadpool` object. **]**
|
||||
|
||||
**NON_THREADPOOL_01_003: [** If any error occurs, `threadpool_create` shall fail and return `NULL`. **]**
|
||||
|
||||
### threadpool_destroy
|
||||
### threadpool_dispose
|
||||
|
||||
```c
|
||||
MOCKABLE_FUNCTION(, void, threadpool_destroy, THREADPOOL_HANDLE, threadpool);
|
||||
MOCKABLE_FUNCTION(, void, threadpool_dispose, THREADPOOL_HANDLE, threadpool);
|
||||
```
|
||||
|
||||
`threadpool_destroy` frees all resources associated with `threadpool`.
|
||||
`threadpool_dispose` frees all resources associated with threadpool.
|
||||
|
||||
**NON_THREADPOOL_01_004: [** If `threadpool` is `NULL`, `threadpool_destroy` shall return. **]**
|
||||
**NON_THREADPOOL_01_004: [** If `threadpool` is `NULL`, `threadpool_dispose` shall return. **]**
|
||||
|
||||
**NON_THREADPOOL_01_005: [** Otherwise, `threadpool_destroy` shall free all resources associated with `threadpool`. **]**
|
||||
**NON_THREADPOOL_01_005: [** Otherwise, `threadpool_dispose` shall free all resources associated with `threadpool`. **]**
|
||||
|
||||
**NON_THREADPOOL_01_006: [** While `threadpool` is OPENING, `threadpool_destroy` shall wait for the open to complete either successfully or with error. **]**
|
||||
**N_O_N_THREADPOOL_01_018: [** Then `threadpool_dispose` shall close the `threadpool`. **]**
|
||||
|
||||
**NON_THREADPOOL_01_007: [** `threadpool_destroy` shall perform an implicit close if `threadpool` is OPEN. **]**
|
||||
**NON_THREADPOOL_01_007: [** `threadpool_dispose` shall perform an implicit close if `threadpool` is OPEN. **]**
|
||||
|
||||
### threadpool_open
|
||||
|
||||
```c
|
||||
MOCKABLE_FUNCTION(, int, threadpool_open, THREADPOOL_HANDLE, threadpool);
|
||||
```
|
||||
|
||||
`threadpool_open` opens the threadpool object so that subsequent calls to `threadpool_schedule_work` can be made.
|
||||
Note: `threadpool_open` will be deprecated and `threadpool_create` will perform additional tasks of `threadpool_open`. This function will exist until all the libraries calling this API are modified to use only `threadpool_create`.
|
||||
`threadpool_open` opens the `threadpool` object so that subsequent calls to `threadpool_schedule_work` can be made.
|
||||
|
||||
**NON_THREADPOOL_01_008: [** If `threadpool` is `NULL`, `threadpool_open` shall fail and return a non-zero value. **]**
|
||||
|
||||
|
@ -99,14 +101,14 @@ MOCKABLE_FUNCTION(, int, threadpool_open, THREADPOOL_HANDLE, threadpool);
|
|||
```c
|
||||
MOCKABLE_FUNCTION(, void, threadpool_close, THREADPOOL_HANDLE, threadpool);
|
||||
```
|
||||
|
||||
`threadpool_close` closes an open `threadpool`.
|
||||
Note: `threadpool_close` will be deprecated and `threadpool_dispose` will perform additional tasks of `threadpool_close`. This function will exist until all the libraries calling this API are modified to use only `threadpool_create`.
|
||||
`threadpool_close` closes an open threadpool.
|
||||
|
||||
**NON_THREADPOOL_01_016: [** If `threadpool` is `NULL`, `threadpool_close` shall return. **]**
|
||||
|
||||
**NON_THREADPOOL_01_017: [** Otherwise, `threadpool_close` shall switch the state to CLOSING. **]**
|
||||
|
||||
**NON_THREADPOOL_01_018: [** Then `threadpool_close` shall close the threadpool, leaving it in a state where an `threadpool_open` can be performed. **]**
|
||||
**NON_THREADPOOL_01_018: [** Then `threadpool_close` shall close the `threadpool`, leaving it in a state where an `threadpool_open` can be performed. **]**
|
||||
|
||||
**NON_THREADPOOL_01_019: [** If `threadpool` is not OPEN, `threadpool_close` shall return. **]**
|
||||
|
||||
|
@ -116,7 +118,7 @@ MOCKABLE_FUNCTION(, void, threadpool_close, THREADPOOL_HANDLE, threadpool);
|
|||
MOCKABLE_FUNCTION(, THREADPOOL_WORK_ITEM_HANDLE, threadpool_create_work_item, THANDLE(THREADPOOL), threadpool, THREADPOOL_WORK_FUNCTION, work_function, void*, work_function_context);
|
||||
```
|
||||
|
||||
`threadpool_create_work_item` creates a work item to be executed by the threadpool. This function separates the creation of the work item from scheduling it so that threadpool_schedule_work_item can be called later and cannot fail.
|
||||
`threadpool_create_work_item` creates a work item to be executed by the threadpool. This function separates the creation of the work item from scheduling it so that `threadpool_schedule_work_item` can be called later and cannot fail.
|
||||
|
||||
**NON_THREADPOOL_05_001: [** If `threadpool` is `NULL`, `threadpool_create_work_item` shall fail and return a `NULL` value. **]**
|
||||
|
||||
|
@ -140,11 +142,11 @@ MOCKABLE_FUNCTION(, int, threadpool_schedule_work_item, THANDLE(THREADPOOL), thr
|
|||
|
||||
`threadpool_schedule_work_item` schedules a work item to be executed by the threadpool. This API can be called multiple times on the same `THREADPOOL_WORK_ITEM_HANDLE` and fails only if the arguments are passed `NULL`.
|
||||
|
||||
**NON_THREADPOOL_05_008: [** If `threadpool` is NULL, `threadpool_schedule_work_item` shall fail and return a `non-zero` value. **]**
|
||||
**NON_THREADPOOL_05_008: [** If `threadpool` is NULL, `threadpool_schedule_work_item` shall fail and return a non-zero value. **]**
|
||||
|
||||
**NON_THREADPOOL_05_009: [** If `work_item_context` is NULL, `threadpool_schedule_work_item` shall fail and return a `non-zero` value. **]**
|
||||
**NON_THREADPOOL_05_009: [** If `work_item_context` is NULL, `threadpool_schedule_work_item` shall fail and return a non-zero value. **]**
|
||||
|
||||
**NON_THREADPOOL_05_010: [** `threadpool_schedule_work_item` shall submit the threadpool work item for execution. **]**
|
||||
**NON_THREADPOOL_05_010: [** `threadpool_schedule_work_item` shall submit the `threadpool` work item for execution. **]**
|
||||
|
||||
### threadpool_destroy_work_item
|
||||
|
||||
|
@ -154,7 +156,7 @@ MOCKABLE_FUNCTION(, void, threadpool_destroy_work_item, THANDLE(THREADPOOL), thr
|
|||
|
||||
`threadpool_destroy_work_item` closes and frees all the member variables in the context of type `THREADPOOL_WORK_ITEM_HANDLE` and then frees the context
|
||||
|
||||
**NON_THREADPOOL_05_011: [ ** If `threadpool` is `NULL`, `threadpool_destroy_work_item` shall fail and return a `non-zero` value. **]**
|
||||
**NON_THREADPOOL_05_011: [ ** If `threadpool` is `NULL`, `threadpool_destroy_work_item` shall fail and return a non-zero value. **]**
|
||||
|
||||
**NON_THREADPOOL_05_012: [** If `work_item_context` is `NULL`, `threadpool_destroy_work_item` shall fail and not do anything before returning. **]**
|
||||
|
||||
|
|
|
@ -129,6 +129,10 @@ MOCKABLE_FUNCTION(, THANDLE(THREADPOOL), threadpool_create, EXECUTION_ENGINE_HAN
|
|||
|
||||
**SRS_THREADPOOL_LINUX_07_010: [** `insert_idx` and `consume_idx` for the task array shall be initialized to 0. **]**
|
||||
|
||||
**S_R_S_THREADPOOL_LINUX_07_020: [** `threadpool_create` shall create `min_thread_count` number of threads for `threadpool` using `ThreadAPI_Create`. **]**
|
||||
|
||||
**S_R_S_THREADPOOL_LINUX_07_022: [** If one of the thread creation fails, `threadpool_create` shall fail and return a non-zero value, terminate all threads already created. **]**
|
||||
|
||||
**SRS_THREADPOOL_LINUX_07_011: [** If any error occurs, `threadpool_create` shall fail and return `NULL`. **]**
|
||||
|
||||
### threadpool_dispose
|
||||
|
@ -137,22 +141,26 @@ MOCKABLE_FUNCTION(, THANDLE(THREADPOOL), threadpool_create, EXECUTION_ENGINE_HAN
|
|||
static void threadpool_dispose(THREADPOOL* threadpool)
|
||||
```
|
||||
|
||||
`threadpool_dispose` frees the resouces associated with `threadpool`.
|
||||
`threadpool_dispose` frees the resouces associated with threadpool.
|
||||
|
||||
**SRS_THREADPOOL_LINUX_07_013: [** `threadpool_destroy` shall perform an implicit close if `threadpool` is open. **]**
|
||||
**SRS_THREADPOOL_LINUX_07_013: [** `threadpool_dispose` shall perform an implicit close if `threadpool` is open. **]**
|
||||
|
||||
**SRS_THREADPOOL_LINUX_07_014: [** `threadpool_destroy` shall destroy the semphore by calling `sem_destroy`. **]**
|
||||
**SRS_THREADPOOL_LINUX_07_014: [** `threadpool_dispose` shall destroy the semphore by calling `sem_destroy`. **]**
|
||||
|
||||
**SRS_THREADPOOL_LINUX_07_015: [** `threadpool_destroy` shall destroy the SRW lock by calling `srw_lock_destroy`. **]**
|
||||
**SRS_THREADPOOL_LINUX_07_015: [** `threadpool_dispose` shall destroy the SRW lock by calling `srw_lock_destroy`. **]**
|
||||
|
||||
**SRS_THREADPOOL_LINUX_07_016: [** `threadpool_destroy` shall free the memory allocated in `threadpool_create`. **]**
|
||||
**S_R_S_THREADPOOL_LINUX_07_089: [** `threadpool_dispose` shall signal all the threads that `threadpool` is closing by calling `InterlockedHL_SetAndWakeAll`. **]**
|
||||
|
||||
**S_R_S_THREADPOOL_LINUX_07_027: [** `threadpool_dispose` shall join all threads in the `threadpool`. **]**
|
||||
|
||||
**SRS_THREADPOOL_LINUX_07_016: [** `threadpool_dispose` shall free the memory allocated in `threadpool_create`. **]**
|
||||
|
||||
### threadpool_open
|
||||
|
||||
```C
|
||||
MOCKABLE_FUNCTION(, int, threadpool_open, THANDLE(THREADPOOL), threadpool);
|
||||
```
|
||||
|
||||
Note: `threadpool_open` will be deprecated and `threadpool_create` will perform additional tasks of `threadpool_open`. This function will exist until all the libraries calling this API are modified to use only `threadpool_create`.
|
||||
`threadpool_open` opens the threadpool.
|
||||
|
||||
**SRS_THREADPOOL_LINUX_07_017: [** If `threadpool` is `NULL`, `threadpool_open` shall fail and return a non-zero value. **]**
|
||||
|
@ -163,7 +171,7 @@ MOCKABLE_FUNCTION(, int, threadpool_open, THANDLE(THREADPOOL), threadpool);
|
|||
|
||||
**SRS_THREADPOOL_LINUX_11_001: [** `threadpool_open` shall initialize internal threapool data items **]**
|
||||
|
||||
**SRS_THREADPOOL_LINUX_07_020: [** `threadpool_open` shall create number of `min_thread_count` threads for `threadpool` using `ThreadAPI_Create`. **]**
|
||||
**SRS_THREADPOOL_LINUX_07_020: [** `threadpool_open` shall create `min_thread_count` number of threads for `threadpool` using `ThreadAPI_Create`. **]**
|
||||
|
||||
**SRS_THREADPOOL_LINUX_07_021: [** If any error occurs, `threadpool_open` shall fail and return a non-zero value. **]**
|
||||
|
||||
|
@ -178,7 +186,7 @@ MOCKABLE_FUNCTION(, int, threadpool_open, THANDLE(THREADPOOL), threadpool);
|
|||
```C
|
||||
MOCKABLE_FUNCTION(, void, threadpool_close, THANDLE(THREADPOOL), threadpool);
|
||||
```
|
||||
|
||||
Note: `threadpool_close` will be deprecated and threadpool_dispose will perform additional tasks of threadpool_close. This function will exist until all the libraries calling this API are modified to use only `threadpool_create`.
|
||||
`threadpool_close` closes the threadpool.
|
||||
|
||||
**SRS_THREADPOOL_LINUX_07_025: [** If `threadpool` is `NULL`, `threadpool_close` shall fail and return. **]**
|
||||
|
@ -439,13 +447,13 @@ MOCKABLE_FUNCTION(, int, threadpool_schedule_work_item, THANDLE(THREADPOOL), thr
|
|||
|
||||
`threadpool_schedule_work_item` schedules a work item to be executed by the threadpool.
|
||||
|
||||
**SRS_THREADPOOL_LINUX_05_010: [** If `threadpool` is `NULL`, `threadpool_schedule_work_item` shall fail and set the return variable with a `non-zero` value. **]**
|
||||
**SRS_THREADPOOL_LINUX_05_010: [** If `threadpool` is `NULL`, `threadpool_schedule_work_item` shall fail and set the return variable with a non-zero value. **]**
|
||||
|
||||
**SRS_THREADPOOL_LINUX_05_011: [** If `threadpool_work_item` is `NULL`, `threadpool_schedule_work_item` shall fail and set the return variable with a `non-zero` value. **]**
|
||||
**SRS_THREADPOOL_LINUX_05_011: [** If `threadpool_work_item` is `NULL`, `threadpool_schedule_work_item` shall fail and set the return variable with a non-zero value. **]**
|
||||
|
||||
**SRS_THREADPOOL_LINUX_05_012: [** `threadpool_schedule_work_item` shall call `sm_exec_begin`. **]**
|
||||
|
||||
**SRS_THREADPOOL_LINUX_05_013: [** If `sm_exec_begin` returns `SM_EXEC_REFUSED`, `threadpool_schedule_work_item` shall fail and set the return variable a `non-zero` value. **]**
|
||||
**SRS_THREADPOOL_LINUX_05_013: [** If `sm_exec_begin` returns `SM_EXEC_REFUSED`, `threadpool_schedule_work_item` shall fail and set the return variable a non-zero value. **]**
|
||||
|
||||
**SRS_THREADPOOL_LINUX_05_014: [** `threadpool_schedule_work_item` shall acquire the `SRW lock` in shared mode by calling `srw_lock_acquire_shared`. **]**
|
||||
|
||||
|
@ -457,7 +465,7 @@ MOCKABLE_FUNCTION(, int, threadpool_schedule_work_item, THANDLE(THREADPOOL), thr
|
|||
|
||||
**SRS_THREADPOOL_LINUX_05_018: [** If the previous task state is not `TASK_NOT_USED` then `threadpool_schedule_work_item` shall increase `task_array` capacity **]**
|
||||
|
||||
- **SRS_THREADPOOL_LINUX_05_019: [** If reallocating the task array fails, `threadpool_schedule_work_item` shall fail by setting the return variable a `non-zero` value and break. **]**
|
||||
- **SRS_THREADPOOL_LINUX_05_019: [** If reallocating the task array fails, `threadpool_schedule_work_item` shall fail by setting the return variable a non-zero value and break. **]**
|
||||
|
||||
- **SRS_THREADPOOL_LINUX_05_020: [ Otherwise, `threadpool_schedule_work_item` shall acquire the SRW lock in exclusive mode by calling srw_lock_acquire_exclusive. ]*/
|
||||
|
||||
|
|
|
@ -56,6 +56,14 @@ MOCKABLE_FUNCTION(, THANDLE(THREADPOOL), threadpool_create, EXECUTION_ENGINE_HAN
|
|||
|
||||
**SRS_THREADPOOL_WIN32_01_025: [** `threadpool_create` shall obtain the PTP_POOL from the execution engine by calling `execution_engine_win32_get_threadpool`. **]**
|
||||
|
||||
**S_R_S_THREADPOOL_WIN32_01_026: [** `threadpool_create` shall initialize a thread pool environment by calling `InitializeThreadpoolEnvironment`. **]**
|
||||
|
||||
**S_R_S_THREADPOOL_WIN32_01_027: [** `threadpool_create` shall set the thread pool for the environment to the pool obtained from the execution engine by calling `SetThreadpoolCallbackPool`. **]**
|
||||
|
||||
**S_R_S_THREADPOOL_WIN32_01_028: [** `threadpool_create` shall create a threadpool cleanup group by calling `CreateThreadpoolCleanupGroup`. **]**
|
||||
|
||||
**S_R_S_THREADPOOL_WIN32_01_029: [** `threadpool_create` shall associate the cleanup group with the just created environment by calling `SetThreadpoolCallbackCleanupGroup`. **]**
|
||||
|
||||
**SRS_THREADPOOL_WIN32_01_003: [** If any error occurs, `threadpool_create` shall fail and return `NULL`. **]**
|
||||
|
||||
### threadpool_dispose
|
||||
|
@ -64,13 +72,21 @@ MOCKABLE_FUNCTION(, THANDLE(THREADPOOL), threadpool_create, EXECUTION_ENGINE_HAN
|
|||
static void threadpool_dispose(THREADPOOL* threadpool)
|
||||
```
|
||||
|
||||
`threadpool_dispose` frees all resources associated with `threadpool`.
|
||||
`threadpool_dispose` frees all resources associated with threadpool.
|
||||
|
||||
**SRS_THREADPOOL_WIN32_01_005: [** `threadpool_dispose` shall free all resources associated with `threadpool`. **]**
|
||||
|
||||
**S_R_S_THREADPOOL_WIN32_01_016: [** If `threadpool` is `NULL`, `threadpool_dispose` shall return. **]**
|
||||
|
||||
**SRS_THREADPOOL_WIN32_01_006: [** While `threadpool` is OPENING or CLOSING, `threadpool_dispose` shall wait for the open to complete either successfully or with error. **]**
|
||||
|
||||
**SRS_THREADPOOL_WIN32_01_007: [** `threadpool_dispose` shall perform an implicit close if `threadpool` is OPEN. **]**
|
||||
**SRS_THREADPOOL_WIN32_01_007: [** `threadpool_dispose` shall perform an implicit close. **]**
|
||||
|
||||
- **S_R_S_THREADPOOL_WIN32_01_030: [** `threadpool_dispose` shall wait for any executing callbacks by calling `CloseThreadpoolCleanupGroupMembers`, passing `FALSE` as `fCancelPendingCallbacks`. **]**
|
||||
|
||||
- **S_R_S_THREADPOOL_WIN32_01_032: [** `threadpool_dispose` shall close the threadpool cleanup group by calling `CloseThreadpoolCleanupGroup`. **]**
|
||||
|
||||
- **S_R_S_THREADPOOL_WIN32_01_033: [** `threadpool_dispose` shall destroy the thread pool environment created in `threadpool_create`. **]**
|
||||
|
||||
**SRS_THREADPOOL_WIN32_42_028: [** `threadpool_dispose` shall decrement the reference count on the `execution_engine`. **]**
|
||||
|
||||
|
@ -79,7 +95,7 @@ static void threadpool_dispose(THREADPOOL* threadpool)
|
|||
```c
|
||||
MOCKABLE_FUNCTION(, int, threadpool_open, THANDLE(THREADPOOL), threadpool);
|
||||
```
|
||||
|
||||
Note: `threadpool_open` will be deprecated and threadpool_create will perform additional tasks of `threadpool_open`. This function will exist until all the libraries calling this API are modified to use only `threadpool_create`.
|
||||
`threadpool_open` opens the threadpool object so that subsequent calls to `threadpool_schedule_work` can be made.
|
||||
|
||||
**SRS_THREADPOOL_WIN32_01_008: [** If `threadpool` is `NULL`, `threadpool_open` shall fail and return a non-zero value. **]**
|
||||
|
@ -107,8 +123,8 @@ MOCKABLE_FUNCTION(, int, threadpool_open, THANDLE(THREADPOOL), threadpool);
|
|||
```c
|
||||
MOCKABLE_FUNCTION(, void, threadpool_close, THANDLE(THREADPOOL), threadpool);
|
||||
```
|
||||
|
||||
`threadpool_close` closes an open `threadpool`.
|
||||
Note: `threadpool_close` will be deprecated and threadpool_dispose will perform additional tasks of `threadpool_close`. This function will exist until all the libraries calling this API are modified to use only `threadpool_create`.
|
||||
`threadpool_close` closes an open threadpool.
|
||||
|
||||
**SRS_THREADPOOL_WIN32_01_016: [** If `threadpool` is `NULL`, `threadpool_close` shall return. **]**
|
||||
|
||||
|
@ -118,7 +134,7 @@ MOCKABLE_FUNCTION(, void, threadpool_close, THANDLE(THREADPOOL), threadpool);
|
|||
|
||||
**SRS_THREADPOOL_WIN32_01_032: [** `threadpool_close` shall close the threadpool cleanup group by calling `CloseThreadpoolCleanupGroup`. **]**
|
||||
|
||||
**SRS_THREADPOOL_WIN32_01_033: [** `threadpool_close` shall destroy the thread pool environment created in `threadpool_open`. **]**
|
||||
**SRS_THREADPOOL_WIN32_01_033: [** `threadpool_close` shall destroy the thread pool environment created in `threadpool_create`. **]**
|
||||
|
||||
**SRS_THREADPOOL_WIN32_01_019: [** If `threadpool` is not OPEN, `threadpool_close` shall return. **]**
|
||||
|
||||
|
@ -302,9 +318,9 @@ MOCKABLE_FUNCTION(, int, threadpool_schedule_work_item, THANDLE(THREADPOOL), thr
|
|||
|
||||
`threadpool_schedule_work_item` schedules a work item to be executed by the threadpool.
|
||||
|
||||
**SRS_THREADPOOL_WIN32_05_011: [** If `threadpool` is NULL, `threadpool_schedule_work_item` shall fail and return a `non-zero` value. **]**
|
||||
**SRS_THREADPOOL_WIN32_05_011: [** If `threadpool` is NULL, `threadpool_schedule_work_item` shall fail and return a non-zero value. **]**
|
||||
|
||||
**SRS_THREADPOOL_WIN32_05_012: [** If `work_item_context` is NULL, `threadpool_schedule_work_item` shall fail and return a `non-zero` value. **]**
|
||||
**SRS_THREADPOOL_WIN32_05_012: [** If `work_item_context` is NULL, `threadpool_schedule_work_item` shall fail and return a non-zero value. **]**
|
||||
|
||||
**SRS_THREADPOOL_WIN32_05_013: [** `threadpool_schedule_work_item` shall call `SubmitThreadpoolWork` to submit the work item for execution. **]**
|
||||
|
||||
|
@ -316,7 +332,7 @@ MOCKABLE_FUNCTION(, void, threadpool_destroy_work_item, THANDLE(THREADPOOL), thr
|
|||
|
||||
`threadpool_destroy_work_item` closes the `ptp_work` member variable in `work_item_context`and then frees the `work_item_context`
|
||||
|
||||
**SRS_THREADPOOL_WIN32_05_014: [ ** If `threadpool` is `NULL`, `threadpool_destroy_work_item` shall fail and return a `non-zero` value. **]**
|
||||
**SRS_THREADPOOL_WIN32_05_014: [ ** If `threadpool` is `NULL`, `threadpool_destroy_work_item` shall fail and return a non-zero value. **]**
|
||||
|
||||
**SRS_THREADPOOL_WIN32_05_015: [** If `work_item_context` is `NULL`, `threadpool_destroy_work_item` shall fail and not do anything before returning. **]**
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче