Create a boost::thread and pass it to a HANDLE - c++

I have the following code:
unsigned long ClassName::fn_StartTesterPresentThread()
{
// m_hTesterPresent is a HANDLE
if (m_hTesterPresent == NULL)
{
DWORD dwThreadId = 0;
m_hTesterPresent = CreateThread(NULL, 0, th_TesterPresent, this, 0, &dwThreadId);
}
return ACTION_SUCCESS;
}
The CreateThread function is Windows-specific, but the code needs to be ported to Linux/non-platform-specific.
I now need a way to create a boost::thread and pass it into the HANDLE m_hTesterPresent.
I was thinking about something like this:
unsigned long Class::fn_StartTesterPresentThread()
{
if (m_hTesterPresent == NULL)
{
DWORD dwThreadId = 0;
boost::thread threadTesterPresent(&m_hTesterPresent);
threadTesterPresent.join();
}
return ACTION_SUCCESS;
}
Is this the correct way? Sadly, I can't yet compile or test because I still have other parts of the project to port.
Furthermore, the project is a DLL and I don't have the client yet that calls the functions in the DLL.
Any help appreciated!

The argument to boost::thread should be a function to call, here th_TesterPresent.
If you are porting this code to non-Windows environments, I suggest you use typedefs to distinguish between the different kinds of HANDLEs.
Then you can have:
#ifndef WINDOWS
typedef boost::thread* THREAD_HANDLE;
typedef boost::mutex MUTEX_HANDLE;
#else
typedef HANDLE THREAD_HANDLE;
typedef HANDLE MUTEX_HANDLE;
#endif
and store THREAD_HANDLE / MUTEX_HANDLE values in various place. Instead of calling OS-specific functions, you can then call generic "createThreadHandle" functions that dispatch to different functions depending on the OS.
Alternatively, you could port your code to an OS-agnostic framework like boost and solve two problems in one go.

Related

How to return value from asynchronous function in dll

My dll has asynchronous function which starts a thread and returns immediately. It accepts handle of event object (type HANDLE) which the thread signals when it is done. This works fine but how can I return result from the function that it passed and no error occurred? A simple bool type will do.
I am thinking of using GetLastError() kind of call to get result of last function but I am not really sold on this way. I also looked at std::future and std::async but I am not sure if I can use that in dll function!? Another option I thought about is to use GetOverlappedResultbut that works usually with file i/o and I don't know if I can use this for a custom function that I have written.
Chad is right callback is safe and easy way to do it
// DLL:
__declspec(dllexport) void (*callback_function)(DWORD ret)=NULL;
DWORD _stdcall thread_function(LPVOID p)
{
// do something ...
if (callback_function) callback_function(some_return_value);
}
// DLL usage
DWORD return_value1=0;
bool done1=false;
void callback_function1(DWORD ret)
{
return_value1=ret;
done1=true;
}
void main()
{
callback_function=callback_function1; // set callbak function for DLL
done1=false; // invalidate return value
// here call you DLL function
for (;!done1;) Sleep(1); // wait for valid result ... also can add some timeout to avoid hang-ups
// now in return_value1 is the valid return value
}
also you can use waitforsingleobject instead
http://msdn.microsoft.com/en-us/library/windows/desktop/ms687032(v=vs.85).aspx

Clone C++ datatype for multiplatform purposes

I have an idea how to make very simple crossplatform (linux/windows) thread function. This is my sample code:
#if LINUX
#include <pthread.h>
ThreadHandle createThread(???* callback, void* data) { //I dont know what is data type of function pointer, sorry
pthread_t handle;
pthread_create(&handle, 0, callback, (void*)data);
return (ThreadHandle)handle;
}
define_data_type ThreadHandle = pthread_t; //I don't know how this is done at all, sorry
#endif
#if WINDOWS
#include <windows.h>
ThreadHandle createThread(???* callback, void* data) {
HANDLE handle = CreateThread(
NULL, // default security attributes
0, // use default stack size
callback, // thread function name
data, // argument to thread function
0, // use default creation flags
NULL); // returns the thread identifier - I don't need this, do I?
}
define_data_type ThreadHandle = HANDLE; //I don't know how this is done at all, sorry
#endif
I'm afraid this will first look like veird question, but keep on mind that I'm beginner, and I need to understand C++. Feel free to edit those parts where I left "i don't know" comments.
If you think this is wrong question, please leave comment about how should I've asked.
Start by having a platform independent header like Thread.h which will abstract all the thread functions
Have platform specific code in *.$platform.cpp files
Obviously your build system should only compile platform relevant code
Now, for specific code
Use something like this to define generic types
typedef unsigned long os_error_t;
typedef void * os_console_handle;
typedef void * os_thread_handle;
typedef void * os_event_handle;
typedef unsigned long os_pid_t;
typedef unsigned long os_thread_id;
On linux, use and call pthread_create(..)
On windows, use and call CreateThread(..)
Read the docs for specific impl
For callback you can use something like
typedef os_error_t (*thread_start_function_t)(void *);
class InternalThreadArgs {
thread_start_function_t m_func;
void *m_pArg;
public:
InternalThreadArgs(thread_start_function_t pf, void *pArg) {
m_func = pf;
m_pArg = pArg;
}
os_error_t Run() {
return m_func(m_pArg);
}
};
Now,
have your abstract method signatures like
os_error_t create_thread(thread_start_function_t pf, void *pArg, os_thread_handle *pHandle);

Serial asynchronous I/O in Windows 7/64

I have a multi-threaded Windows program which is doing serial port asynchronous I/O through "raw" Win API calls. It is working perfectly fine on any Windows version except Windows 7/64.
The problem is that the program can find and setup the COM port just fine, but it cannot send nor receive any data. No matter if I compile the binary in Win XP or 7, I cannot send/receive on Win 7/64. Compatibility mode, run as admin etc does not help.
I have managed to narrow down the problem to the FileIOCompletionRoutine callback. Every time it is called, dwErrorCode is always 0, dwNumberOfBytesTransfered is always 0. GetOverlappedResult() from inside the function always return TRUE (everything ok). It seems to set the lpNumberOfBytesTransferred correctly. But the lpOverlapped parameter is corrupt, it is a garbage pointer pointing at garbage values.
I can see that it is corrupt by either checking in the debugger what address the correct OVERLAPPED struct is allocated at, or by setting a temp. global variable to point at it.
My question is: why does this happen, and why does it only happen on Windows 7/64? Is there some issue with calling convention that I am not aware of? Or is the overlapped struct treated differently somehow?
Posting relevant parts of the code below:
class ThreadedComport : public Comport
{
private:
typedef struct
{
OVERLAPPED overlapped;
ThreadedComport* caller; /* add user data to struct */
} OVERLAPPED_overlap;
OVERLAPPED_overlap _send_overlapped;
OVERLAPPED_overlap _rec_overlapped;
...
static void WINAPI _send_callback (DWORD dwErrorCode,
DWORD dwNumberOfBytesTransfered,
LPOVERLAPPED lpOverlapped);
static void WINAPI _receive_callback (DWORD dwErrorCode,
DWORD dwNumberOfBytesTransfered,
LPOVERLAPPED lpOverlapped);
...
};
Open/close is done in a base class that has no multi-threading nor asynchronous I/O implemented:
void Comport::open (void)
{
char port[20];
DCB dcbCommPort;
COMMTIMEOUTS ctmo_new = {0};
if(_is_open)
{
close();
}
sprintf(port, "\\\\.\\COM%d", TEXT(_port_number));
_hcom = CreateFile(port,
GENERIC_READ | GENERIC_WRITE,
0,
0,
OPEN_EXISTING,
0,
0);
if(_hcom == INVALID_HANDLE_VALUE)
{
// error handling
}
GetCommTimeouts(_hcom, &_ctmo_old);
ctmo_new.ReadTotalTimeoutConstant = 10;
ctmo_new.ReadTotalTimeoutMultiplier = 0;
ctmo_new.WriteTotalTimeoutMultiplier = 0;
ctmo_new.WriteTotalTimeoutConstant = 0;
if(SetCommTimeouts(_hcom, &ctmo_new) == FALSE)
{
// error handling
}
dcbCommPort.DCBlength = sizeof(DCB);
if(GetCommState(_hcom, &(DCB)dcbCommPort) == FALSE)
{
// error handling
}
// setup DCB, this seems to work fine
dcbCommPort.DCBlength = sizeof(DCB);
dcbCommPort.BaudRate = baudrate_int;
if(_parity == PAR_NONE)
{
dcbCommPort.fParity = 0; /* disable parity */
}
else
{
dcbCommPort.fParity = 1; /* enable parity */
}
dcbCommPort.Parity = (uint8)_parity;
dcbCommPort.ByteSize = _databits;
dcbCommPort.StopBits = _stopbits;
SetCommState(_hcom, &(DCB)dcbCommPort);
}
void Comport::close (void)
{
if(_hcom != NULL)
{
SetCommTimeouts(_hcom, &_ctmo_old);
CloseHandle(_hcom);
_hcom = NULL;
}
_is_open = false;
}
The whole multi-threading and event handling mechanism is rather complex, relevant parts are:
Send
result = WriteFileEx (_hcom, // handle to output file
(void*)_write_data, // pointer to input buffer
send_buf_size, // number of bytes to write
(LPOVERLAPPED)&_send_overlapped, // pointer to async. i/o data
(LPOVERLAPPED_COMPLETION_ROUTINE )&_send_callback);
Receive
result = ReadFileEx (_hcom, // handle to output file
(void*)_read_data, // pointer to input buffer
_MAX_MESSAGE_LENGTH, // number of bytes to read
(OVERLAPPED*)&_rec_overlapped, // pointer to async. i/o data
(LPOVERLAPPED_COMPLETION_ROUTINE )&_receive_callback);
Callback functions
void WINAPI ThreadedComport::_send_callback (DWORD dwErrorCode,
DWORD dwNumberOfBytesTransfered,
LPOVERLAPPED lpOverlapped)
{
ThreadedComport* _this = ((OVERLAPPED_overlap*)lpOverlapped)->caller;
if(dwErrorCode == 0) // no errors
{
if(dwNumberOfBytesTransfered > 0)
{
_this->_data_sent = dwNumberOfBytesTransfered;
}
}
SetEvent(lpOverlapped->hEvent);
}
void WINAPI ThreadedComport::_receive_callback (DWORD dwErrorCode,
DWORD dwNumberOfBytesTransfered,
LPOVERLAPPED lpOverlapped)
{
if(dwErrorCode == 0) // no errors
{
if(dwNumberOfBytesTransfered > 0)
{
ThreadedComport* _this = ((OVERLAPPED_overlap*)lpOverlapped)->caller;
_this->_bytes_read = dwNumberOfBytesTransfered;
}
}
SetEvent(lpOverlapped->hEvent);
}
EDIT
Updated: I have spent most of the day on the theory that the OVERLAPPED variable went out of scope before the callback is executed. I have verified that this never happens and I have even tried to declare the OVERLAPPED struct as static, same problem remains. If the OVERLAPPED struct had gone out of scope, I would expect the callback to point at the memory location where the struct was previously allocated, but it doesn't, it points somewhere else, at an entirely unfamiliar memory location. Why it does that, I have no idea.
Maybe Windows 7/64 makes an internal hardcopy of the OVERLAPPED struct? I can see how that would cause this behavior, since I am relying on additional parameters sneaked in at the end of the struct (which seems like a hack to me, but apparently I got that "hack" from official MSDN examples).
I have also tried to change calling convention but this doesn't work at all, if I change it then the program crashes. (The standard calling convention causes it to crash, whatever standard is, cdecl? __fastcall also causes a crash.) The calling conventions that work are __stdcall, WINAPI and CALLBACK. I think these are all same names for __stdcall and I read somewhere that Win 64 ignores that calling convention anyhow.
It would seem that the callback is executed because of some "spurious disturbance" in Win 7/64 generating false callback calls with corrupt or irrelevant parameters.
Multi-thread race conditions is another theory, but in the scenario I am running to reproduce the bug, there is only one thread, and I can confirm that the thread calling ReadFileEx is the same one that is executing the callback.
I have found the problem, it turned out to be annoyingly simple.
In CreateFile(), I did not specify FILE_FLAG_OVERLAPPED. For reasons unknown, this was not necessary on 32-bit Windows. But if you forget it on 64-bit Windows, it will apparently still generate callbacks with the FileIOCompletionRoutine, but they have corrupted parameters.
I haven't found any documentation of this change of behavior anywhere; perhaps it was just an internal bug fix in Windows, since the older documentation also specifies that you must have FILE_FLAG_OVERLAPPED set.
As for my specific case, the bug appeared because I had a base class that assumed synchronous I/O, which has then been inherited by a class using asynchronous I/O.

std::thread - naming your thread

The new C++ has this std::thread type. Works like a charm.
Now I would like to give each thread a name for more easy debugging (like java allows you to).
With pthreads I would do:
pthread_setname_np(pthread_self(), "thread_name");
but how can I do this with c++0x?
I know it uses pthreads underneath on Linux systems, but I would like to make my application portable. Is it possible at all?
A portable way to do this is to maintain a map of names, keyed by the thread's ID, obtained from thread::get_id(). Alternatively, as suggested in the comments, you could use a thread_local variable, if you only need to access the name from within the thread.
If you didn't need portability, then you could get the underlying pthread_t from thread::native_handle() and do whatever platform-specific shenanigans you like with that. Be aware that the _np on the thread naming functions means "not posix", so they aren't guaranteed to be available on all pthreads implementations.
An attempt at making a wrapper to deal with many Linuxes as well as Windows. Please edit as needed.
#ifdef _WIN32
#include <windows.h>
const DWORD MS_VC_EXCEPTION=0x406D1388;
#pragma pack(push,8)
typedef struct tagTHREADNAME_INFO
{
DWORD dwType; // Must be 0x1000.
LPCSTR szName; // Pointer to name (in user addr space).
DWORD dwThreadID; // Thread ID (-1=caller thread).
DWORD dwFlags; // Reserved for future use, must be zero.
} THREADNAME_INFO;
#pragma pack(pop)
void SetThreadName(uint32_t dwThreadID, const char* threadName)
{
// DWORD dwThreadID = ::GetThreadId( static_cast<HANDLE>( t.native_handle() ) );
THREADNAME_INFO info;
info.dwType = 0x1000;
info.szName = threadName;
info.dwThreadID = dwThreadID;
info.dwFlags = 0;
__try
{
RaiseException( MS_VC_EXCEPTION, 0, sizeof(info)/sizeof(ULONG_PTR), (ULONG_PTR*)&info );
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
}
}
void SetThreadName( const char* threadName)
{
SetThreadName(GetCurrentThreadId(),threadName);
}
void SetThreadName( std::thread* thread, const char* threadName)
{
DWORD threadId = ::GetThreadId( static_cast<HANDLE>( thread->native_handle() ) );
SetThreadName(threadId,threadName);
}
#elif defined(__linux__)
#include <sys/prctl.h>
void SetThreadName( const char* threadName)
{
prctl(PR_SET_NAME,threadName,0,0,0);
}
#else
void SetThreadName(std::thread* thread, const char* threadName)
{
auto handle = thread->native_handle();
pthread_setname_np(handle,threadName);
}
#endif
You can use std::thread::native_handle to get the underlaying implementation defined thread. There is no standard function for that natively.
You can find an example here.
For windows [debugger], you can easily use the "normal" method;
http://msdn.microsoft.com/en-gb/library/xcb2z8hs.aspx
Just need the thread id which you can obtain via
#include <windows.h>
DWORD ThreadId = ::GetThreadId( static_cast<HANDLE>( mThread.native_handle() ) );
I've both seen this done in a system predating c++11 (where we basically invented our own Thread class that was very similar to std::thread) and in one I wrote fairly recently.
Basically, the pool really puts std::thread 2 layers down- you have a PoolThread class that contains a std::thread plus metadata like its name, ID, etc. and the the control structure that links it to its controlling pool, and the ThreadPool itself. You want to use thread pools in most threaded code for several reasons:
1) You can hide all the explicit "detach", "join", start thread on std::thread construction, etc. from users. That produces MUCH safer & cleaner code.
2) Better resource management: Too many threads will cripple performance even more than having too few. A well-built pool can do advanced things like automatic load balancing and cleaning-up hung or deadlocked threads.
3) Thread reuse: std::thread by itself is easiest to use by running every parallel task on its own thread. But thread creation & destruction are expensive, and can easily swamp the speed boost from parallel processing if you're not careful. So, it usually makes more sense to have pool threads that pull work tasks from a queue and only exit after receiving some signal.
4) Error handling: std::thread is just an execution context. If the task you're running on it throws an un-handled exception or std::thread ITSELF fails, the process will just crash right there. To do fault-tolerant multithreading, you need a Pool or something similar that can quickly catch such things and at least emit meaningful error messages before the process dies.
In header file do:
const std::string & ThreadName(const std::string name="");
In src file do:
const std::string & ThreadName(const std::string name)
{
static std::atomic_int threadCount{0};
const thread_local std::string _name = name + std::to_string(threadCount.fetch_add(1));
return _name;
}
Usage:
void myThread()
{
ThreadName("myThread"); // Call once at very beginning of your thread creation
...
std::cout << ThreadName() << std::endl; // Anyplace in your code
}

C++: _beginthreadex, thread function name not showing in Visual Studio Threads window

I recently learnt that ::_beginthreadex() is always preferable to ::CreateThread(), so I changed all my calls that used ::CreateThread().
The only downside is that I no longer see the thread function's name in Visual Studio's Threads window making it hard to quickly identify threads. I assume this was somehow done automatically by the debugger when I used ::CreateThread(), since the parameters are exactly the same, I just changed the name of the function used.
Is there any way to keep using ::_beginthreadex() and to see the thread's name in the Threads window of Visual Studio?
This happens because _beginthreadex() calls CreateThread() with its own thread function that calls the one you specify (so the debugger uses the _threadstartex function name - the one that _beginthreadex() invokes).
You can manually set the thread name yourself using the SetThreadName() example from MSDN. What you might want to do is create your own wrapper for _beginthreadex() that maybe looks something like:
uintptr_t startthreadex(
void* security,
unsigned stacksize,
unsigned (__stdcall * threadproc) (void *),
void* args,
unsigned flags,
unsigned * pThread_id,
char* thread_name)
{
unsigned alt_thread_id;
if (!pThread_id) {
pThread_id = & alt_thread_id;
}
uintptr_t result = _beginthreadex(security, stacksize, threadproc, args, flgas, pThread_id);
if (result == 0) return result;
SetThreadName( *pThread_id, thread_name);
}
Now you can call startthreadex() instead of _beginthreadex() and pass it a thread name. A small advantage to this is that if you use the same function to run several threads, you can easily give them each unique names that reflect the parameters passed ot the thread or whatever.
If you want the thread name to automatically take be the thread proc function name as the debugger's thread name, you could make a wrapper macro that stringizes the function name parameter (all it takes is another level of indirection or to to solve any problem...).
Here's SetThreadName() (it's from http://msdn.microsoft.com/en-us/library/xcb2z8hs.aspx):
//
// Usage: SetThreadName (-1, "MainThread");
//
#include <windows.h>
const DWORD MS_VC_EXCEPTION=0x406D1388;
#pragma pack(push,8)
typedef struct tagTHREADNAME_INFO
{
DWORD dwType; // Must be 0x1000.
LPCSTR szName; // Pointer to name (in user addr space).
DWORD dwThreadID; // Thread ID (-1=caller thread).
DWORD dwFlags; // Reserved for future use, must be zero.
} THREADNAME_INFO;
#pragma pack(pop)
void SetThreadName( DWORD dwThreadID, char* threadName)
{
THREADNAME_INFO info;
info.dwType = 0x1000;
info.szName = threadName;
info.dwThreadID = dwThreadID;
info.dwFlags = 0;
__try
{
RaiseException( MS_VC_EXCEPTION, 0, sizeof(info)/sizeof(ULONG_PTR), (ULONG_PTR*)&info );
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
}
}
There is no particular advantage with using _beginthreadex over CreateThread. The CRT functions would eventually call CreateThread only.
You should read:
Windows threading: _beginthread vs _beginthreadex vs CreateThread C++
http://www.codeguru.com/forum/showthread.php?t=371305
http://social.msdn.microsoft.com/forums/en-US/vclanguage/thread/c727ae29-5a7a-42b6-ad0b-f6b21c1180b2