Don't use classes nested in function definitions since they cause problems

for the VC7.1 linker.
This commit is contained in:
chris_kohlhoff 2006-02-26 22:27:51 +00:00
parent 2fab66c440
commit 03b978c7f9
2 changed files with 80 additions and 73 deletions

View File

@ -74,42 +74,8 @@ public:
if (h == &task_handler_) if (h == &task_handler_)
{ {
// Helper class to perform operations on block exit. task_cleanup c(lock, handler_queue_,
class cleanup handler_queue_end_, task_handler_);
{
public:
cleanup(asio::detail::mutex::scoped_lock& lock,
handler_base*& handler_queue, handler_base*& handler_queue_end,
handler_base& task_handler)
: lock_(lock),
handler_queue_(handler_queue),
handler_queue_end_(handler_queue_end),
task_handler_(task_handler)
{
}
~cleanup()
{
// Reinsert the task at the end of the handler queue.
lock_.lock();
task_handler_.next_ = 0;
if (handler_queue_end_)
{
handler_queue_end_->next_ = &task_handler_;
handler_queue_end_ = &task_handler_;
}
else
{
handler_queue_ = handler_queue_end_ = &task_handler_;
}
}
private:
asio::detail::mutex::scoped_lock& lock_;
handler_base*& handler_queue_;
handler_base*& handler_queue_end_;
handler_base& task_handler_;
} c(lock, handler_queue_, handler_queue_end_, task_handler_);
// Run the task. May throw an exception. Only block if the handler // Run the task. May throw an exception. Only block if the handler
// queue is empty, otherwise we want to return as soon as possible to // queue is empty, otherwise we want to return as soon as possible to
@ -118,27 +84,7 @@ public:
} }
else else
{ {
// Helper class to perform operations on block exit. handler_cleanup c(lock, outstanding_work_);
class cleanup
{
public:
cleanup(asio::detail::mutex::scoped_lock& lock,
int& outstanding_work)
: lock_(lock),
outstanding_work_(outstanding_work)
{
}
~cleanup()
{
lock_.lock();
--outstanding_work_;
}
private:
asio::detail::mutex::scoped_lock& lock_;
int& outstanding_work_;
} c(lock, outstanding_work_);
// Invoke the handler. May throw an exception. // Invoke the handler. May throw an exception.
h->call(allocator_); // call() deletes the handler object h->call(allocator_); // call() deletes the handler object
@ -357,6 +303,65 @@ private:
Handler handler_; Handler handler_;
}; };
// Helper class to perform task-related operations on block exit.
class task_cleanup
{
public:
task_cleanup(asio::detail::mutex::scoped_lock& lock,
handler_base*& handler_queue, handler_base*& handler_queue_end,
handler_base& task_handler)
: lock_(lock),
handler_queue_(handler_queue),
handler_queue_end_(handler_queue_end),
task_handler_(task_handler)
{
}
~task_cleanup()
{
// Reinsert the task at the end of the handler queue.
lock_.lock();
task_handler_.next_ = 0;
if (handler_queue_end_)
{
handler_queue_end_->next_ = &task_handler_;
handler_queue_end_ = &task_handler_;
}
else
{
handler_queue_ = handler_queue_end_ = &task_handler_;
}
}
private:
asio::detail::mutex::scoped_lock& lock_;
handler_base*& handler_queue_;
handler_base*& handler_queue_end_;
handler_base& task_handler_;
};
// Helper class to perform handler-related operations on block exit.
class handler_cleanup
{
public:
handler_cleanup(asio::detail::mutex::scoped_lock& lock,
int& outstanding_work)
: lock_(lock),
outstanding_work_(outstanding_work)
{
}
~handler_cleanup()
{
lock_.lock();
--outstanding_work_;
}
private:
asio::detail::mutex::scoped_lock& lock_;
int& outstanding_work_;
};
// Mutex to protect access to internal data. // Mutex to protect access to internal data.
asio::detail::mutex mutex_; asio::detail::mutex mutex_;

View File

@ -72,6 +72,23 @@ public:
::CreateIoCompletionPort(sock_as_handle, iocp_.handle, 0, 0); ::CreateIoCompletionPort(sock_as_handle, iocp_.handle, 0, 0);
} }
struct auto_work
{
auto_work(win_iocp_io_service& io_service)
: io_service_(io_service)
{
io_service_.work_started();
}
~auto_work()
{
io_service_.work_finished();
}
private:
win_iocp_io_service& io_service_;
};
// Run the event processing loop. // Run the event processing loop.
void run() void run()
{ {
@ -100,22 +117,7 @@ public:
{ {
// Ensure that the io_service does not exit due to running out of work // Ensure that the io_service does not exit due to running out of work
// while we make the upcall. // while we make the upcall.
struct auto_work auto_work work(*this);
{
auto_work(win_iocp_io_service& io_service)
: io_service_(io_service)
{
io_service_.work_started();
}
~auto_work()
{
io_service_.work_finished();
}
private:
win_iocp_io_service& io_service_;
} work(*this);
// Dispatch the operation. // Dispatch the operation.
operation* op = static_cast<operation*>(overlapped); operation* op = static_cast<operation*>(overlapped);