essay on programming languages, computer science, information techonlogies and all.

Sunday, December 22, 2013

Using Boost io_service to synchronize with user theread

When writing GUI application using MFC, you can encounter a situation that ask you to call some GUI method in a non-GUI thread. This can happens when there are more than 1 threads running - quite common case in nowaday. When application call methods like GetAfxMainWnd() in non-GUI thread, the application crashes. AfxGetMainWnd() stores information at thread local storage which can't be access in the non-GUI thread. Refer below code. Foo runs a non-GUI thread which call a GUI-thread only method that can crash an application.

To get over this problem, you have to make a GUI thread to call a method for the non-GUI thread. If we just put the method on the GUI class holding GUI thread - CMainFrame in above, it makes the GUI class to be dependant on a completely separate class. It is a bad design. And also it is not possible to know all the different methods that will comes up to be called in GUI thread. If we add methods on the GUI-thread whenever a new stuff comes up, the code is constantly changing. Refer below code snippet that demonstart this scenario. In here, the exact implementation detail of synchronization is not shown .e.g SignalGUI(), WaitForGUIToFinish(), IsGUISignaled(). It can be implemented with semaphore and list structure.

With boost IOService, this situation can be elegantly solved with good separation between GUI and non-GUI class. Controller class has io_service and it acts like a bridge between GUI and non-GUI class. The non-GUI class can Post() it's own method that has to run in a GUI thread. The GUI class can just call Controller's Poll() method and that will call non-GUI's posted method subsequently Above Controller() provides a good isolation between two different entity and also reusable as it doesn't depend how the GUI and non-GUI class are made.

No comments: