mirror of
https://github.com/samba-team/samba.git
synced 2024-12-23 17:34:34 +03:00
Next step disentangling async_req from NTSTATUS
Now I need to document this :-)
This commit is contained in:
parent
af736923a5
commit
d3f9b0fab6
@ -70,6 +70,14 @@ struct async_req *async_req_new(TALLOC_CTX *mem_ctx)
|
||||
return result;
|
||||
}
|
||||
|
||||
static void async_req_finish(struct async_req *req, enum async_req_state state)
|
||||
{
|
||||
req->state = state;
|
||||
if (req->async.fn != NULL) {
|
||||
req->async.fn(req);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief An async request has successfully finished
|
||||
* @param[in] req The finished request
|
||||
@ -81,30 +89,23 @@ struct async_req *async_req_new(TALLOC_CTX *mem_ctx)
|
||||
|
||||
void async_req_done(struct async_req *req)
|
||||
{
|
||||
req->error = 0;
|
||||
req->state = ASYNC_REQ_DONE;
|
||||
if (req->async.fn != NULL) {
|
||||
req->async.fn(req);
|
||||
}
|
||||
async_req_finish(req, ASYNC_REQ_DONE);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief An async request has seen an error
|
||||
* @param[in] req The request with an error
|
||||
* @param[in] status The error code
|
||||
* @param[in] error The error code
|
||||
*
|
||||
* async_req_done is to be used by implementors of async requests. When a
|
||||
* request can not successfully completed, the implementation should call this
|
||||
* function with the appropriate status code.
|
||||
*/
|
||||
|
||||
void async_req_error(struct async_req *req, uint32_t error)
|
||||
void async_req_error(struct async_req *req, uint64_t error)
|
||||
{
|
||||
req->error = error;
|
||||
req->state = ASYNC_REQ_ERROR;
|
||||
if (req->async.fn != NULL) {
|
||||
req->async.fn(req);
|
||||
}
|
||||
async_req_finish(req, ASYNC_REQ_USER_ERROR);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -129,6 +130,32 @@ static void async_trigger(struct tevent_context *ev, struct tevent_timer *te,
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Helper function for nomem check
|
||||
* @param[in] p The pointer to be checked
|
||||
* @param[in] req The request being processed
|
||||
*
|
||||
* Convenience helper to easily check alloc failure within a callback
|
||||
* implementing the next step of an async request.
|
||||
*
|
||||
* Call pattern would be
|
||||
* \code
|
||||
* p = talloc(mem_ctx, bla);
|
||||
* if (async_req_ntnomem(p, req)) {
|
||||
* return;
|
||||
* }
|
||||
* \endcode
|
||||
*/
|
||||
|
||||
bool async_req_nomem(const void *p, struct async_req *req)
|
||||
{
|
||||
if (p != NULL) {
|
||||
return false;
|
||||
}
|
||||
async_req_finish(req, ASYNC_REQ_NO_MEMORY);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Finish a request before it started processing
|
||||
* @param[in] req The finished request
|
||||
@ -143,7 +170,7 @@ static void async_trigger(struct tevent_context *ev, struct tevent_timer *te,
|
||||
*/
|
||||
|
||||
bool async_post_error(struct async_req *req, struct tevent_context *ev,
|
||||
uint32_t error)
|
||||
uint64_t error)
|
||||
{
|
||||
req->error = error;
|
||||
|
||||
@ -154,16 +181,17 @@ bool async_post_error(struct async_req *req, struct tevent_context *ev,
|
||||
return true;
|
||||
}
|
||||
|
||||
bool async_req_is_error(struct async_req *req, uint32_t *error)
|
||||
bool async_req_is_error(struct async_req *req, enum async_req_state *state,
|
||||
uint64_t *error)
|
||||
{
|
||||
if (req->state < ASYNC_REQ_DONE) {
|
||||
return true;
|
||||
if (req->state == ASYNC_REQ_DONE) {
|
||||
return false;
|
||||
}
|
||||
if (req->state == ASYNC_REQ_ERROR) {
|
||||
if (req->state == ASYNC_REQ_USER_ERROR) {
|
||||
*error = req->error;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
*state = req->state;
|
||||
return true;
|
||||
}
|
||||
|
||||
static void async_req_timedout(struct tevent_context *ev,
|
||||
@ -171,18 +199,17 @@ static void async_req_timedout(struct tevent_context *ev,
|
||||
struct timeval now,
|
||||
void *priv)
|
||||
{
|
||||
struct async_req *req = talloc_get_type_abort(
|
||||
priv, struct async_req);
|
||||
struct async_req *req = talloc_get_type_abort(priv, struct async_req);
|
||||
TALLOC_FREE(te);
|
||||
async_req_nterror(req, NT_STATUS_IO_TIMEOUT);
|
||||
async_req_finish(req, ASYNC_REQ_TIMED_OUT);
|
||||
}
|
||||
|
||||
bool async_req_set_timeout(struct async_req *req, struct tevent_context *ev,
|
||||
struct timeval to)
|
||||
{
|
||||
return (tevent_add_timer(ev, req,
|
||||
timeval_current_ofs(to.tv_sec, to.tv_usec),
|
||||
async_req_timedout, req)
|
||||
return (tevent_add_timer(
|
||||
ev, req, timeval_current_ofs(to.tv_sec, to.tv_usec),
|
||||
async_req_timedout, req)
|
||||
!= NULL);
|
||||
}
|
||||
|
||||
|
@ -40,9 +40,17 @@ enum async_req_state {
|
||||
*/
|
||||
ASYNC_REQ_DONE,
|
||||
/**
|
||||
* an error has occured
|
||||
* A user error has occured
|
||||
*/
|
||||
ASYNC_REQ_ERROR
|
||||
ASYNC_REQ_USER_ERROR,
|
||||
/**
|
||||
* Request timed out
|
||||
*/
|
||||
ASYNC_REQ_TIMED_OUT,
|
||||
/**
|
||||
* No memory in between
|
||||
*/
|
||||
ASYNC_REQ_NO_MEMORY
|
||||
};
|
||||
|
||||
/**
|
||||
@ -94,7 +102,7 @@ struct async_req {
|
||||
* This status can be queried in the async completion function. It
|
||||
* will be set to 0 when everything went fine.
|
||||
**/
|
||||
uint32_t error;
|
||||
uint64_t error;
|
||||
|
||||
/**
|
||||
* @brief What to do on completion
|
||||
@ -121,12 +129,15 @@ char *async_req_print(TALLOC_CTX *mem_ctx, struct async_req *req);
|
||||
|
||||
void async_req_done(struct async_req *req);
|
||||
|
||||
void async_req_error(struct async_req *req, uint32_t error);
|
||||
void async_req_error(struct async_req *req, uint64_t error);
|
||||
|
||||
bool async_req_nomem(const void *p, struct async_req *req);
|
||||
|
||||
bool async_post_error(struct async_req *req, struct tevent_context *ev,
|
||||
uint32_t error);
|
||||
uint64_t error);
|
||||
|
||||
bool async_req_is_error(struct async_req *req, uint32_t *error);
|
||||
bool async_req_is_error(struct async_req *req, enum async_req_state *state,
|
||||
uint64_t *error);
|
||||
|
||||
bool async_req_set_timeout(struct async_req *req, struct tevent_context *ev,
|
||||
struct timeval to);
|
||||
|
@ -23,32 +23,6 @@
|
||||
#include "lib/util/dlinklist.h"
|
||||
#include "lib/async_req/async_req_ntstatus.h"
|
||||
|
||||
/**
|
||||
* @brief Helper function for nomem check
|
||||
* @param[in] p The pointer to be checked
|
||||
* @param[in] req The request being processed
|
||||
*
|
||||
* Convenience helper to easily check alloc failure within a callback
|
||||
* implementing the next step of an async request.
|
||||
*
|
||||
* Call pattern would be
|
||||
* \code
|
||||
* p = talloc(mem_ctx, bla);
|
||||
* if (async_req_ntnomem(p, req)) {
|
||||
* return;
|
||||
* }
|
||||
* \endcode
|
||||
*/
|
||||
|
||||
bool async_req_ntnomem(const void *p, struct async_req *req)
|
||||
{
|
||||
if (p != NULL) {
|
||||
return false;
|
||||
}
|
||||
async_req_nterror(req, NT_STATUS_NO_MEMORY);
|
||||
return true;
|
||||
}
|
||||
|
||||
void async_req_nterror(struct async_req *req, NTSTATUS status)
|
||||
{
|
||||
async_req_error(req, NT_STATUS_V(status));
|
||||
@ -62,13 +36,27 @@ bool async_post_ntstatus(struct async_req *req, struct tevent_context *ev,
|
||||
|
||||
bool async_req_is_nterror(struct async_req *req, NTSTATUS *status)
|
||||
{
|
||||
uint32_t error = NT_STATUS_V(NT_STATUS_INTERNAL_ERROR);
|
||||
enum async_req_state state;
|
||||
uint64_t error;
|
||||
|
||||
if (async_req_is_error(req, &error)) {
|
||||
*status = NT_STATUS(error);
|
||||
return true;
|
||||
if (!async_req_is_error(req, &state, &error)) {
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
switch (state) {
|
||||
case ASYNC_REQ_USER_ERROR:
|
||||
*status = NT_STATUS(error);
|
||||
break;
|
||||
case ASYNC_REQ_TIMED_OUT:
|
||||
*status = NT_STATUS_IO_TIMEOUT;
|
||||
break;
|
||||
case ASYNC_REQ_NO_MEMORY:
|
||||
*status = NT_STATUS_NO_MEMORY;
|
||||
break;
|
||||
default:
|
||||
*status = NT_STATUS_INTERNAL_ERROR;
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
NTSTATUS async_req_simple_recv_ntstatus(struct async_req *req)
|
||||
|
@ -32,6 +32,4 @@ bool async_req_is_nterror(struct async_req *req, NTSTATUS *status);
|
||||
|
||||
NTSTATUS async_req_simple_recv_ntstatus(struct async_req *req);
|
||||
|
||||
bool async_req_ntnomem(const void *p, struct async_req *req);
|
||||
|
||||
#endif
|
||||
|
@ -1077,7 +1077,7 @@ static void open_socket_out_connected(struct async_req *subreq)
|
||||
subreq = async_connect_send(state, state->ev, state->fd,
|
||||
(struct sockaddr *)&state->ss,
|
||||
state->salen);
|
||||
if (async_req_ntnomem(subreq, req)) {
|
||||
if (async_req_nomem(subreq, req)) {
|
||||
return;
|
||||
}
|
||||
if (!async_req_set_timeout(subreq, state->ev,
|
||||
@ -1209,7 +1209,7 @@ static void open_socket_out_defer_waited(struct async_req *subreq)
|
||||
|
||||
subreq = open_socket_out_send(state, state->ev, &state->ss,
|
||||
state->port, state->timeout);
|
||||
if (async_req_ntnomem(subreq, req)) {
|
||||
if (async_req_nomem(subreq, req)) {
|
||||
return;
|
||||
}
|
||||
subreq->async.fn = open_socket_out_defer_connected;
|
||||
|
@ -96,7 +96,7 @@ static void wb_req_read_len(struct async_req *subreq)
|
||||
subreq = recvall_send(
|
||||
req, state->ev, state->fd, (uint32 *)(state->wb_req)+1,
|
||||
sizeof(struct winbindd_request) - sizeof(uint32), 0);
|
||||
if (async_req_ntnomem(subreq, req)) {
|
||||
if (async_req_nomem(subreq, req)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -135,7 +135,7 @@ static void wb_req_read_main(struct async_req *subreq)
|
||||
|
||||
state->wb_req->extra_data.data = TALLOC_ARRAY(
|
||||
state->wb_req, char, state->wb_req->extra_len + 1);
|
||||
if (async_req_ntnomem(state->wb_req->extra_data.data, req)) {
|
||||
if (async_req_nomem(state->wb_req->extra_data.data, req)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -144,7 +144,7 @@ static void wb_req_read_main(struct async_req *subreq)
|
||||
subreq = recvall_send(
|
||||
req, state->ev, state->fd, state->wb_req->extra_data.data,
|
||||
state->wb_req->extra_len, 0);
|
||||
if (async_req_ntnomem(subreq, req)) {
|
||||
if (async_req_nomem(subreq, req)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -244,7 +244,7 @@ static void wb_req_write_main(struct async_req *subreq)
|
||||
subreq = sendall_send(state, state->ev, state->fd,
|
||||
state->wb_req->extra_data.data,
|
||||
state->wb_req->extra_len, 0);
|
||||
if (async_req_ntnomem(subreq, req)) {
|
||||
if (async_req_nomem(subreq, req)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -343,7 +343,7 @@ static void wb_resp_read_len(struct async_req *subreq)
|
||||
subreq = recvall_send(
|
||||
req, state->ev, state->fd, (uint32 *)(state->wb_resp)+1,
|
||||
sizeof(struct winbindd_response) - sizeof(uint32), 0);
|
||||
if (async_req_ntnomem(subreq, req)) {
|
||||
if (async_req_nomem(subreq, req)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -375,7 +375,7 @@ static void wb_resp_read_main(struct async_req *subreq)
|
||||
|
||||
state->wb_resp->extra_data.data = TALLOC_ARRAY(
|
||||
state->wb_resp, char, extra_len+1);
|
||||
if (async_req_ntnomem(state->wb_resp->extra_data.data, req)) {
|
||||
if (async_req_nomem(state->wb_resp->extra_data.data, req)) {
|
||||
return;
|
||||
}
|
||||
((char *)state->wb_resp->extra_data.data)[extra_len] = 0;
|
||||
@ -383,7 +383,7 @@ static void wb_resp_read_main(struct async_req *subreq)
|
||||
subreq = recvall_send(
|
||||
req, state->ev, state->fd, state->wb_resp->extra_data.data,
|
||||
extra_len, 0);
|
||||
if (async_req_ntnomem(subreq, req)) {
|
||||
if (async_req_nomem(subreq, req)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -484,7 +484,7 @@ static void wb_resp_write_main(struct async_req *subreq)
|
||||
state, state->ev, state->fd,
|
||||
state->wb_resp->extra_data.data,
|
||||
state->wb_resp->length - sizeof(struct winbindd_response), 0);
|
||||
if (async_req_ntnomem(subreq, req)) {
|
||||
if (async_req_nomem(subreq, req)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -463,7 +463,7 @@ static void wb_open_pipe_connect_nonpriv_done(struct async_req *subreq)
|
||||
|
||||
subreq = wb_int_trans_send(state, state->ev, state->wb_ctx->fd,
|
||||
&state->wb_req);
|
||||
if (async_req_ntnomem(subreq, req)) {
|
||||
if (async_req_nomem(subreq, req)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -496,7 +496,7 @@ static void wb_open_pipe_ping_done(struct async_req *subreq)
|
||||
|
||||
subreq = wb_int_trans_send(state, state->ev, state->wb_ctx->fd,
|
||||
&state->wb_req);
|
||||
if (async_req_ntnomem(subreq, req)) {
|
||||
if (async_req_nomem(subreq, req)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -526,7 +526,7 @@ static void wb_open_pipe_getpriv_done(struct async_req *subreq)
|
||||
subreq = wb_connect_send(state, state->ev, state->wb_ctx,
|
||||
(char *)wb_resp->extra_data.data);
|
||||
TALLOC_FREE(wb_resp);
|
||||
if (async_req_ntnomem(subreq, req)) {
|
||||
if (async_req_nomem(subreq, req)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -582,7 +582,7 @@ static void wb_trigger_trans(struct async_req *req)
|
||||
|
||||
subreq = wb_open_pipe_send(state, state->ev, state->wb_ctx,
|
||||
state->need_priv);
|
||||
if (async_req_ntnomem(subreq, req)) {
|
||||
if (async_req_nomem(subreq, req)) {
|
||||
return;
|
||||
}
|
||||
subreq->async.fn = wb_trans_connect_done;
|
||||
@ -592,7 +592,7 @@ static void wb_trigger_trans(struct async_req *req)
|
||||
|
||||
subreq = wb_int_trans_send(state, state->ev, state->wb_ctx->fd,
|
||||
state->wb_req);
|
||||
if (async_req_ntnomem(subreq, req)) {
|
||||
if (async_req_nomem(subreq, req)) {
|
||||
return;
|
||||
}
|
||||
subreq->async.fn = wb_trans_done;
|
||||
@ -665,7 +665,7 @@ static bool wb_trans_retry(struct async_req *req,
|
||||
}
|
||||
|
||||
subreq = async_wait_send(state, state->ev, timeval_set(1, 0));
|
||||
if (async_req_ntnomem(subreq, req)) {
|
||||
if (async_req_nomem(subreq, req)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -691,7 +691,7 @@ static void wb_trans_retry_wait_done(struct async_req *subreq)
|
||||
|
||||
subreq = wb_open_pipe_send(state, state->ev, state->wb_ctx,
|
||||
state->need_priv);
|
||||
if (async_req_ntnomem(subreq, req)) {
|
||||
if (async_req_nomem(subreq, req)) {
|
||||
return;
|
||||
}
|
||||
subreq->async.fn = wb_trans_connect_done;
|
||||
@ -715,7 +715,7 @@ static void wb_trans_connect_done(struct async_req *subreq)
|
||||
|
||||
subreq = wb_int_trans_send(state, state->ev, state->wb_ctx->fd,
|
||||
state->wb_req);
|
||||
if (async_req_ntnomem(subreq, req)) {
|
||||
if (async_req_nomem(subreq, req)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -432,7 +432,7 @@ static void cli_pull_read_done(struct async_req *read_req)
|
||||
state->start_offset + state->requested,
|
||||
request_thistime);
|
||||
|
||||
if (async_req_ntnomem(new_req, state->req)) {
|
||||
if (async_req_nomem(new_req, state->req)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -269,7 +269,7 @@ static void rpc_read_done(struct async_req *subreq)
|
||||
state->data + state->num_read,
|
||||
state->size - state->num_read,
|
||||
state->transport->priv);
|
||||
if (async_req_ntnomem(subreq, req)) {
|
||||
if (async_req_nomem(subreq, req)) {
|
||||
return;
|
||||
}
|
||||
subreq->async.fn = rpc_read_done;
|
||||
@ -350,7 +350,7 @@ static void rpc_write_done(struct async_req *subreq)
|
||||
state->data + state->num_written,
|
||||
state->size - state->num_written,
|
||||
state->transport->priv);
|
||||
if (async_req_ntnomem(subreq, req)) {
|
||||
if (async_req_nomem(subreq, req)) {
|
||||
return;
|
||||
}
|
||||
subreq->async.fn = rpc_write_done;
|
||||
@ -512,7 +512,7 @@ static void get_complete_frag_got_header(struct async_req *subreq)
|
||||
state, state->ev, state->cli->transport,
|
||||
(uint8_t *)(prs_data_p(state->pdu) + RPC_HEADER_LEN),
|
||||
state->prhdr->frag_len - RPC_HEADER_LEN);
|
||||
if (async_req_ntnomem(subreq, req)) {
|
||||
if (async_req_nomem(subreq, req)) {
|
||||
return;
|
||||
}
|
||||
subreq->async.fn = get_complete_frag_got_rest;
|
||||
@ -1138,7 +1138,7 @@ static void cli_api_pipe_write_done(struct async_req *subreq)
|
||||
}
|
||||
|
||||
state->rdata = TALLOC_ARRAY(state, uint8_t, RPC_HEADER_LEN);
|
||||
if (async_req_ntnomem(state->rdata, req)) {
|
||||
if (async_req_nomem(state->rdata, req)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1150,7 +1150,7 @@ static void cli_api_pipe_write_done(struct async_req *subreq)
|
||||
subreq = state->transport->read_send(state, state->ev, state->rdata,
|
||||
RPC_HEADER_LEN,
|
||||
state->transport->priv);
|
||||
if (async_req_ntnomem(subreq, req)) {
|
||||
if (async_req_nomem(subreq, req)) {
|
||||
return;
|
||||
}
|
||||
subreq->async.fn = cli_api_pipe_read_done;
|
||||
@ -1336,7 +1336,7 @@ static void rpc_api_pipe_trans_done(struct async_req *subreq)
|
||||
*/
|
||||
rdata_copy = (char *)memdup(rdata, rdata_len);
|
||||
TALLOC_FREE(rdata);
|
||||
if (async_req_ntnomem(rdata_copy, req)) {
|
||||
if (async_req_nomem(rdata_copy, req)) {
|
||||
return;
|
||||
}
|
||||
prs_give_memory(&state->incoming_frag, rdata_copy, rdata_len, true);
|
||||
@ -1344,7 +1344,7 @@ static void rpc_api_pipe_trans_done(struct async_req *subreq)
|
||||
/* Ensure we have enough data for a pdu. */
|
||||
subreq = get_complete_frag_send(state, state->ev, state->cli,
|
||||
&state->rhdr, &state->incoming_frag);
|
||||
if (async_req_ntnomem(subreq, req)) {
|
||||
if (async_req_nomem(subreq, req)) {
|
||||
return;
|
||||
}
|
||||
subreq->async.fn = rpc_api_pipe_got_pdu;
|
||||
@ -1436,7 +1436,7 @@ static void rpc_api_pipe_got_pdu(struct async_req *subreq)
|
||||
|
||||
subreq = get_complete_frag_send(state, state->ev, state->cli,
|
||||
&state->rhdr, &state->incoming_frag);
|
||||
if (async_req_ntnomem(subreq, req)) {
|
||||
if (async_req_nomem(subreq, req)) {
|
||||
return;
|
||||
}
|
||||
subreq->async.fn = rpc_api_pipe_got_pdu;
|
||||
@ -2235,7 +2235,7 @@ static void rpc_api_pipe_req_write_done(struct async_req *subreq)
|
||||
subreq = rpc_api_pipe_send(state, state->ev, state->cli,
|
||||
&state->outgoing_frag,
|
||||
RPC_RESPONSE);
|
||||
if (async_req_ntnomem(subreq, req)) {
|
||||
if (async_req_nomem(subreq, req)) {
|
||||
return;
|
||||
}
|
||||
subreq->async.fn = rpc_api_pipe_req_done;
|
||||
@ -2246,7 +2246,7 @@ static void rpc_api_pipe_req_write_done(struct async_req *subreq)
|
||||
state->cli->transport,
|
||||
(uint8_t *)prs_data_p(&state->outgoing_frag),
|
||||
prs_offset(&state->outgoing_frag));
|
||||
if (async_req_ntnomem(subreq, req)) {
|
||||
if (async_req_nomem(subreq, req)) {
|
||||
return;
|
||||
}
|
||||
subreq->async.fn = rpc_api_pipe_req_write_done;
|
||||
|
@ -174,7 +174,7 @@ static void get_anon_ipc_negprot_done(struct async_req *subreq)
|
||||
}
|
||||
|
||||
subreq = cli_session_setup_guest_send(state, state->ev, state->cli);
|
||||
if (async_req_ntnomem(subreq, req)) {
|
||||
if (async_req_nomem(subreq, req)) {
|
||||
return;
|
||||
}
|
||||
subreq->async.fn = get_anon_ipc_sesssetup_done;
|
||||
@ -198,7 +198,7 @@ static void get_anon_ipc_sesssetup_done(struct async_req *subreq)
|
||||
|
||||
subreq = cli_tcon_andx_send(state, state->ev, state->cli,
|
||||
"IPC$", "IPC", NULL, 0);
|
||||
if (async_req_ntnomem(subreq, req)) {
|
||||
if (async_req_nomem(subreq, req)) {
|
||||
return;
|
||||
}
|
||||
subreq->async.fn = get_anon_ipc_tcon_done;
|
||||
|
Loading…
Reference in New Issue
Block a user