Opened 11 years ago

Closed 10 years ago

#6654 closed Bugs (invalid)

deadline_timer may makes dll can't be freed

Reported by: weiyuemin@… Owned by: chris_kohlhoff
Milestone: To Be Determined Component: asio
Version: Boost 1.49.0 Severity: Problem
Keywords: deadline_timer block Cc:

Description

When I use boost::asio::deadline_timer in a dll, FreeLibrary will be blocked. When I commented the deadline_timer, things become ok.

I compile my program on Visual Studio 2010(without sp), and Win Xp sp3. dll was built as Debug configuration, using /MDd

below is my code in main():

	HMODULE hmod2 = LoadLibraryA("tDll2.dll");
	printf("tDll2.dll loaded\n");

	for (;;)
	{
		char cmd[100];
		scanf("%s", cmd);

		if (strcmp(cmd, "init") == 0)
		{
			void_func _init = (void_func)GetProcAddress(hmod2, "init");
			_init();
			printf("init ok\n");
		}
		else if (strcmp(cmd, "uninit") == 0)
		{
			void_func _uninit = (void_func)GetProcAddress(hmod2, "uninit");
			_uninit();
			printf("uninit ok\n");
		}
		else if (strcmp(cmd, "exit") == 0)
		{
			FreeLibrary(hmod2);
			printf("tFreeLib.dll free\n");
			break;
		}
	}

code of tDll2.cpp in tDll2.dll

boost::asio::io_service client_ioservice;

boost::asio::io_service::work* client_ioservice_virtual_work;

boost::thread* th;

void run()
{
	boost::asio::deadline_timer timer(client_ioservice);

	boost::system::error_code error;
	
	client_ioservice.run(error);

	if (error)
	{
		printf("error: %d\n", error.value());
	}

	delete th;

	printf("finish\n");
}

TDLL2_API void init(void)
{
	client_ioservice_virtual_work = new boost::asio::io_service::work(client_ioservice);
	th = new boost::thread(run);
}

TDLL2_API void uninit(void)
{
	delete client_ioservice_virtual_work;
}

this statement printf("finish\n"); is successfully executed, the DllMain is also successfully returned, but FreeLibrary(hmod2); blocks.

When I commented this line:

  boost::asio::deadline_timer timer(client_ioservice);

things become ok.

Change History (3)

comment:1 by weiyuemin@…, 11 years ago

The console input and output:

tDll2.dll loaded
init
init ok
uninit
uninit ok
finish
exit

It blocks on

FreeLibrary(hmod2);

comment:2 by weiyuemin@…, 11 years ago

declare client_ioservice as boost::asio::io_service*, and manually release the io_service* would avoid this problem.

if I declare io_service as a global variable in dll, or wrap it with shared_ptr, then it(the io_service) can't be properly released.

comment:3 by chris_kohlhoff, 10 years ago

Resolution: invalid
Status: newclosed

To correctly clean up global io_service objects in a DLL, call

boost::asio::detail::win_thread::set_terminate_threads(true)

at some point prior to the FreeLibrary call.

Note: See TracTickets for help on using tickets.