Ensure contexts get released after the upcall is complete.

This commit is contained in:
chris 2003-12-30 00:43:21 +00:00
parent 16b88425ae
commit 9d57f38680
3 changed files with 22 additions and 19 deletions

View File

@ -76,7 +76,7 @@ public:
// Ensure that the context has been acquired. Returns true if the context // Ensure that the context has been acquired. Returns true if the context
// was acquired and the operation can proceed immediately, false otherwise. // was acquired and the operation can proceed immediately, false otherwise.
template <typename Completion_Context> template <typename Completion_Context>
bool acquire_context(HANDLE iocp, Completion_Context& context) bool acquire_context(HANDLE iocp, Completion_Context context)
{ {
if (context_acquired_) if (context_acquired_)
return true; return true;
@ -93,7 +93,7 @@ public:
// Ensure that the context has been released. // Ensure that the context has been released.
template <typename Completion_Context> template <typename Completion_Context>
void release_context(Completion_Context& context) void release_context(Completion_Context context)
{ {
if (context_acquired_) if (context_acquired_)
{ {
@ -178,7 +178,7 @@ public:
struct completion_operation struct completion_operation
: public operation : public operation
{ {
completion_operation(Handler handler, Completion_Context& context, completion_operation(Handler handler, Completion_Context context,
bool context_acquired) bool context_acquired)
: operation(context_acquired), : operation(context_acquired),
handler_(handler), handler_(handler),
@ -210,12 +210,12 @@ public:
private: private:
Handler handler_; Handler handler_;
Completion_Context& context_; Completion_Context context_;
}; };
// Notify the demuxer that an operation has completed. // Notify the demuxer that an operation has completed.
template <typename Handler, typename Completion_Context> template <typename Handler, typename Completion_Context>
void operation_completed(Handler handler, Completion_Context& context, void operation_completed(Handler handler, Completion_Context context,
bool allow_nested_delivery) bool allow_nested_delivery)
{ {
if (context.try_acquire()) if (context.try_acquire())
@ -245,7 +245,7 @@ public:
// Notify the demuxer of an operation that started and finished immediately. // Notify the demuxer of an operation that started and finished immediately.
template <typename Handler, typename Completion_Context> template <typename Handler, typename Completion_Context>
void operation_immediate(Handler handler, Completion_Context& context, void operation_immediate(Handler handler, Completion_Context context,
bool allow_nested_delivery) bool allow_nested_delivery)
{ {
operation_started(); operation_started();

View File

@ -156,7 +156,7 @@ public:
: public win_iocp_demuxer_service::operation : public win_iocp_demuxer_service::operation
{ {
public: public:
sendto_operation(Handler handler, Completion_Context& context) sendto_operation(Handler handler, Completion_Context context)
: win_iocp_demuxer_service::operation(false), : win_iocp_demuxer_service::operation(false),
handler_(handler), handler_(handler),
context_(context) context_(context)
@ -171,6 +171,7 @@ public:
socket_error error(last_error); socket_error error(last_error);
do_upcall(handler_, error, bytes_transferred); do_upcall(handler_, error, bytes_transferred);
release_context(context_);
delete this; delete this;
return true; return true;
} }
@ -189,15 +190,14 @@ public:
private: private:
Handler handler_; Handler handler_;
Completion_Context& context_; Completion_Context context_;
}; };
// Start an asynchronous send. The data being sent must be valid for the // Start an asynchronous send. The data being sent must be valid for the
// lifetime of the asynchronous operation. // lifetime of the asynchronous operation.
template <typename Address, typename Handler, typename Completion_Context> template <typename Address, typename Handler, typename Completion_Context>
void async_sendto(impl_type& impl, const void* data, size_t length, void async_sendto(impl_type& impl, const void* data, size_t length,
const Address& destination, Handler handler, const Address& destination, Handler handler, Completion_Context context)
Completion_Context& context)
{ {
sendto_operation<Handler, Completion_Context>* sendto_op = sendto_operation<Handler, Completion_Context>* sendto_op =
new sendto_operation<Handler, Completion_Context>(handler, context); new sendto_operation<Handler, Completion_Context>(handler, context);
@ -250,7 +250,7 @@ public:
{ {
public: public:
recvfrom_operation(Address& address, Handler handler, recvfrom_operation(Address& address, Handler handler,
Completion_Context& context) Completion_Context context)
: win_iocp_demuxer_service::operation(false), : win_iocp_demuxer_service::operation(false),
address_(address), address_(address),
address_size_(address.native_size()), address_size_(address.native_size()),
@ -273,6 +273,7 @@ public:
address_.native_size(address_size_); address_.native_size(address_size_);
socket_error error(last_error); socket_error error(last_error);
do_upcall(handler_, error, bytes_transferred); do_upcall(handler_, error, bytes_transferred);
release_context(context_);
delete this; delete this;
return true; return true;
} }
@ -293,7 +294,7 @@ public:
Address& address_; Address& address_;
int address_size_; int address_size_;
Handler handler_; Handler handler_;
Completion_Context& context_; Completion_Context context_;
}; };
// Start an asynchronous receive. The buffer for the data being received and // Start an asynchronous receive. The buffer for the data being received and
@ -301,7 +302,7 @@ public:
// asynchronous operation. // asynchronous operation.
template <typename Address, typename Handler, typename Completion_Context> template <typename Address, typename Handler, typename Completion_Context>
void async_recvfrom(impl_type& impl, void* data, size_t max_length, void async_recvfrom(impl_type& impl, void* data, size_t max_length,
Address& sender_address, Handler handler, Completion_Context& context) Address& sender_address, Handler handler, Completion_Context context)
{ {
recvfrom_operation<Address, Handler, Completion_Context>* recvfrom_op = recvfrom_operation<Address, Handler, Completion_Context>* recvfrom_op =
new recvfrom_operation<Address, Handler, Completion_Context>( new recvfrom_operation<Address, Handler, Completion_Context>(

View File

@ -129,7 +129,7 @@ public:
: public win_iocp_demuxer_service::operation : public win_iocp_demuxer_service::operation
{ {
public: public:
send_operation(Handler handler, Completion_Context& context) send_operation(Handler handler, Completion_Context context)
: win_iocp_demuxer_service::operation(false), : win_iocp_demuxer_service::operation(false),
handler_(handler), handler_(handler),
context_(context) context_(context)
@ -144,6 +144,7 @@ public:
socket_error error(last_error); socket_error error(last_error);
do_upcall(handler_, error, bytes_transferred); do_upcall(handler_, error, bytes_transferred);
release_context(context_);
delete this; delete this;
return true; return true;
} }
@ -162,14 +163,14 @@ public:
private: private:
Handler handler_; Handler handler_;
Completion_Context& context_; Completion_Context context_;
}; };
// Start an asynchronous send. The data being sent must be valid for the // Start an asynchronous send. The data being sent must be valid for the
// lifetime of the asynchronous operation. // lifetime of the asynchronous operation.
template <typename Handler, typename Completion_Context> template <typename Handler, typename Completion_Context>
void async_send(impl_type& impl, const void* data, size_t length, void async_send(impl_type& impl, const void* data, size_t length,
Handler handler, Completion_Context& context) Handler handler, Completion_Context context)
{ {
send_operation<Handler, Completion_Context>* send_op = send_operation<Handler, Completion_Context>* send_op =
new send_operation<Handler, Completion_Context>(handler, context); new send_operation<Handler, Completion_Context>(handler, context);
@ -214,7 +215,7 @@ public:
: public win_iocp_demuxer_service::operation : public win_iocp_demuxer_service::operation
{ {
public: public:
recv_operation(Handler handler, Completion_Context& context) recv_operation(Handler handler, Completion_Context context)
: win_iocp_demuxer_service::operation(false), : win_iocp_demuxer_service::operation(false),
handler_(handler), handler_(handler),
context_(context) context_(context)
@ -229,6 +230,7 @@ public:
socket_error error(last_error); socket_error error(last_error);
do_upcall(handler_, error, bytes_transferred); do_upcall(handler_, error, bytes_transferred);
release_context(context_);
delete this; delete this;
return true; return true;
} }
@ -247,14 +249,14 @@ public:
private: private:
Handler handler_; Handler handler_;
Completion_Context& context_; Completion_Context context_;
}; };
// Start an asynchronous receive. The buffer for the data being received // Start an asynchronous receive. The buffer for the data being received
// must be valid for the lifetime of the asynchronous operation. // must be valid for the lifetime of the asynchronous operation.
template <typename Handler, typename Completion_Context> template <typename Handler, typename Completion_Context>
void async_recv(impl_type& impl, void* data, size_t max_length, void async_recv(impl_type& impl, void* data, size_t max_length,
Handler handler, Completion_Context& context) Handler handler, Completion_Context context)
{ {
recv_operation<Handler, Completion_Context>* recv_op recv_operation<Handler, Completion_Context>* recv_op
= new recv_operation<Handler, Completion_Context>(handler, context); = new recv_operation<Handler, Completion_Context>(handler, context);