Boost logo

Boost Users :

Subject: [Boost-users] [asio] io_service use in dll leads to service_registry crash
From: joshr (joshrehm_at_[hidden])
Date: 2009-02-17 03:20:34


Configuration:
1) Boost 1.37
2) Visual Studio 2008
3) Windows executable using boost's multi-threaded static library, using a
static linked multi-threaded run time.
4) A dll I have as part of the project is compiled with the same settings.
5) MFC is not used.

The executable creates an io_service (io) and pool of worker threads, each
calling io.run(). Afterwards, the executable begins loading DLLs I've
written to add specific functionality (i.e plugins). Each of these plugins
are passed the executable's io_service so that they can perform asynchronous
work against the thread pool.

One of the DLLs creates a boost::asio::ip::tcp::acceptor object, passing the
io_service to its constructor. This, in turn, eventually calls use_service,
which creates a new service and associates it with the service_registry.
This is all happening in the DLL.

At shut down, I begin unloading the DLLs, giving each a chance to shut down
everything (which they do). I then call FreeLibrary() on the DLL's HMODULE
handle.

After my application completes shutdown, all the destructors hit, as
expected. When the destructor of the service_registry hits, I believe its
linked list of services is still pointing to a service located in the memory
space of the DLL. This results in a crash.

I believe this is the case as I can track the pointer to the
acceptor_service in a Watch Window. The pointers and the object remain
valid until I call "FreeLibrary", at which point they become worthless.

I think this is because the DLL and the executable have their own CRT memory
space, due to the way I'm linking in the CRT. The service for the acceptor
is being created in the DLL's space. When FreeLibrary is called, this space
is released to the OS, making the pointer to the object worthless.

If that's the case, I believe I'll need to supply my own service creation
routine for the DLLs so that the services are created in my executable's
memory space. Is this possible? Is there a way to get the service_registry
to release a service when it's no longer in use anywhere, or to specify my
own new/delete routines the use_service calls should use?

Or, is using ASIO in a DLL like this a really really bad idea? If that's the
case, how can I tell what other objects in boost could cause these sorts of
problems?

I'll try to get a project together that reproduces the issue as soon as I
can. I can't use the code I have at the moment as it is proprietary.

Thanks for any input anyone can provide.

-- 
View this message in context: http://www.nabble.com/-asio--io_service-use-in-dll-leads-to-service_registry-crash-tp22052497p22052497.html
Sent from the Boost - Users mailing list archive at Nabble.com.

Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net