Author Archives: Nicolas Riousset

Getting list control events for a CListView

Imagine you have a CView derived view, like a CListView. You would like to do some treatments when events occurs on the list control ,like a double click. Since you don’t know the control ID of the CListCtrl in the CListView, you can’t just do a :

ON_NOTIFY(NM_DBLCLK, IDC_VIEWLISTCTRL, OnDblclkList)

This is the utilitiy of ON_NOTIFY_REFLECT

ON_NOTIFY(NM_DBLCLK, OnDblclkList)

Try it, it’s magic, it works !

Concurrent access to a small variable

When multithread-programming, you obviously need some synchronization mechanisms, such as semaphores, critical sections. This avoids that two threads access a resource at the same time, one for writing, the other one for reading.

Until now, I was cautiously protecting any variable concurrently accessed with those mechanisms.

And it took me a while to realize that it is not always necessary. As long as your variable is small enough to be read or set in one row from memory, you don’t need to protect it because a thread modifying this variable cannot be interrupted during the modification. The size of variables depends on your type of processor : must not exceed 32 bits on a 32 bits processo, 64 on a 64 bits processor.

Storing thread local using Thread Local Storage (TLS)

Have you ever needed to store data locally to a thread ? For example, let’s say that you want to implement a GetLastErrorMsg() function. This function would complement the standard GetLastError() one by providing a string description of the last error.

How would you implement it ? You need to store the error description on a per thread basis. Will you use a map whose key would be the thread ID and data the error message ? Since you don’t know when threads terminate, when will you delete entries of the map ? What happens if a thread terminates and a new one starts with the same thread ID ? This is definitely not a good approach !

A nicer and easier solution is to use the __declspec( thread ) directive (http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vclang/html/_pluslang_the_thread_attribute.asp).

This directive allows you to specify that a global or member variable is local to a thread. Each time you will use the variable, it will the one specific to the thread, and will be deallocated once it is terminated.

The following code illustrates the use of this directive for the implementation of the GetLastErrorMsg() function.

The thread local storage can be used dynamically too, using the TlsAlloc(), LocalAlloc(), TlsSetValue() and TlsGetValue() functions. This is useful when working with DLL to store Data when threads attach to and detach from the DLL. See the MSDN article about this : “Using Thread Local Storage in a Dynamic-Link Library” (http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dllproc/base/using_thread_local_storage_in_a_dynamic_link_library.asp)

#include "stdafx.h"
#include "myError.h"
using namespace std;

__declspec( thread ) char g_szMsg[256] = "";

 const char* GetMyLastErrorMsg() { return g_szMsg; }

void SetMyLastErrorMsg( const char* szMsg) {
    strcpy( g_szMsg, szMsg); 
}

UINT MyThread( LPVOID pParam )
{
    int iDelay = (int)pParam;
    char szMsg[ 256 ];
    sprintf( szMsg, "Thread %d Message %d", GetCurrentThreadId(), iDelay );
    SetMyLastErrorMsg( szMsg );
    cout << "Set " << szMsg << endl;
    Sleep( iDelay );
    cout << "Get " << GetMyLastErrorMsg() << endl;
    return 0;
} // UINT MyThread

int main(int argc, char* argv[])
{
    CWinThread* pThread = NULL;
    for ( int i = 1; i <= 10; i++ )
    {
        pThread = AfxBeginThread( MyThread, (LPVOID)(i * 1000) );
    }

    WaitForSingleObject( pThread->m_hThread, INFINITE );
    return 0;
}