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.

Thursday, December 19, 2013

Using MSBUILD

Using MSBUILD and making a build process has advantage on other building tools - e.g. nants ... - and that is IDE. When project file is loaded in Visudal Studio IDE and when project is compiled in build process, there is no difference. So just write code and test it in the IDE is enough to run build process.

But to be consistent on the build result across number of project, it should have a common configuration setting that applies to all the project. This can be easily done by just taking out common part of project and import it in the project configuration. Refer below code snippet. There is Import which asks for BuildUnitTest.Default.props. This file can contains all the common setting across all the unit test that is based on the boot unit test framework.

Now the BuildUnitTest.Default.props can be looked like below. Note setting like OutDir and IntDir. By using this common project file, all the project can emit the generated output file to the OutDir which is consitently named location and all the intermediate file can go to the consitently named IntDir. And note the Debug and Release usage to make consistent setting applying to all the project that import this file.

After having number of this kind os project, it is time to weave those together and make a one project file that can build all the projects. Refer below BuildAll.proj. All solution files are listed at the SolutionToBuild. And all unit test that can be run can be liseted at AfterBuild.

And time to write a simple batch file that can kick off the build process. Refer below BuildAll.bat.

Note that this BuildAll.bat can be used in the command line with vcavr32.bat set. Command window can have below setting. This way of making build process doesn't ask for any other tools. Just Visual Studio - demonstrated in here with 2010 - is enough and can be extended to various ways without much effort and learning.

Saturday, December 14, 2013

Using Git - setup SSH server

People starts to have more than 1 computer to play with. At my case, I have two PCs and 1 laptop and 1 tablet. I use one PC for work and the other PC for private matter and 1 laptop for work and private in mobile. I like to go to a cafe and work at there with my laptop. I see lots of people come to cafe with their laptop. Nowaday, most of popular cafe has power socket at their table or nearby wall. And of course WIFI.

This convenience isn't that convenient when it comes to move around files between PC and laptop. As a software developer, I need to be able to share source code between these computers. Sometimes those files are for work or private or public source code.

I can put all the files in some server and try to download and modify and upload. Or the server can be a source server. At this case, you need to have a server with a fixed IP for this purpose. This asks for money most of the case.

There are another way. You can use a Git. Git is a distributed version control. With Git, you can write code with any of your computer and share it between computer easily.

Roughly speaking, each computer has it's own source repository. After you write code, you will 'commit' it to the local repository which is keeps the changes in it's own computer. Then you will 'push' the committed change to a global repository which can reside in any of your computer. This global repository is where all the changes resides made by all the computer. This repository doesn't have to be on the web. It can be one of your computer. Then you can use another PC or laptop to 'pull' the changes from the global repository. Then makes changes and 'commit' and then 'push'

The distributed part of Git comes handy when you want to see the changed history. The local repository also has all the changed history what global repository has. When you 'push' the changes, all the committed part comes up to the global repository. And then when you 'pull', the local repository gets history of all the changes made by different computer through global repository.

The global repository should be accessible in every computer you have. One way to achieve this is to run a SSH server. This SSH is a gateway that allows other computer to access the computer. Other computer can read/write files in the global repository through SSH server.

SSH server asks a public key for each user. It can be generated using puttygen like below screen shot. You will send the saved public key to the SSH server administrator but keeps the private key in private. Server administrator knows your name and it's public key. And later, when you try to access the server with your name, the SSH server will ask for matched private key to let you in.

Then as SSH Server administrator, you should register you as an user. In here, refer below screen shot with Bitvise SSH Server. You will add an user in the account and then add pulic key you generated using puttygen.

Now when you use Git, you need to use the matched private key to log in the SSH server. Refer below screen shot using TortoiseGit. You can select your private key to log on specific SSH server. In here, I used my computer as SSH server so 'localhost'

After successful log-in, the tortoise git will execute commands of Git which resides at git installer folder e.g. "C:\Program Files (x86)\Git\libexec\git-core". You need to put this path at the environmental variable PATH. Otherwise, the SSH server will just terminate just after executing any git command. e.g. cmd.exe /c git-upload-pack "F:\depo\my_repo.git" - in this case if git-upload-pack is not in path, the cmd.exe just returns without any error.