Mike Kaplinskiy <mike.kaplinskiy(a)gmail.com> writes:
> + wsa->read = HeapAlloc( GetProcessHeap(), 0, sizeof(*wsa->read) );
> + if (!wsa->read)
> + {
> + status = STATUS_NO_MEMORY;
> + goto finish;
> + }
> + wsa->read->hSocket = wsa->accept_socket;
> + wsa->read->flags = 0;
> + wsa->read->addr = NULL;
> + wsa->read->addrlen.ptr = NULL;
> + wsa->read->n_iovecs = 1;
> + wsa->read->first_iovec = 0;
> + /* Includes 1 iovec, and that's all we need */
> + wsa->read->iovec[0].iov_base = wsa->buf;
> + wsa->read->iovec[0].iov_len = wsa->data_len;
> + SERVER_START_REQ( register_async )
> + {
> + req->type = ASYNC_TYPE_READ;
> + req->async.handle = wine_server_obj_handle( wsa->accept_socket );
> + req->async.callback = wine_server_client_ptr( WS2_async_recv_accept );
> + req->async.iosb = wine_server_client_ptr( iosb );
> + req->async.arg = wine_server_client_ptr( wsa );
> + status = wine_server_call( req );
> + }
> + SERVER_END_REQ;
> +
> + if (status != STATUS_PENDING)
> + goto finish;
> +
> + return STATUS_SUCCESS;
> +
> +finish:
> + iosb->u.Status = status;
> + iosb->Information = 0;
> +
> + if (wsa->user_overlapped->hEvent)
> + SetEvent(wsa->user_overlapped->hEvent);
> + if (wsa->cvalue)
> + WS_AddCompletion( HANDLE2SOCKET(wsa->listen_socket), wsa->cvalue, iosb->u.Status, iosb->Information );
> + HeapFree( GetProcessHeap(), 0, wsa->read );
> + HeapFree( GetProcessHeap(), 0, wsa );
> +
> + return status;
> +}
You cannot allocate or free memory in an async callback, because it can
be called from a signal handler. All needed memory needs to be allocated
beforehand, and freed in the user apc callback.
--
Alexandre Julliard
julliard(a)winehq.org