Locking on Multithreaded openssl is not working - c++

I have a server. When I try to run the server with multi threading, it crashes. After that I found, I have to manually provide locking in openssl to avoid crashing. After providing static lock also, server gets crashing. I will attach my code here. can anyone say what's wrong in it?
Code:
BIO *bio_err = NULL;
static pthread_mutex_t *lock_cs;
static long *lock_count;
void pthreads_locking_callback(int mode, int type, const char *file,int line)
{
if (mode & CRYPTO_LOCK) {
pthread_mutex_lock(&(lock_cs[type]));
lock_count[type]++;
} else {
pthread_mutex_unlock(&(lock_cs[type]));
}
}
void pthreads_thread_id(CRYPTO_THREADID *tid)
{
unsigned long data = (unsigned long)pthread_self();
CRYPTO_THREADID_set_numeric(tid, (unsigned long)data);
}
void thread_setup(void)
{
int i;
lock_cs = (pthread_mutex_t*)OPENSSL_malloc(CRYPTO_num_locks()* sizeof(pthread_mutex_t));
lock_count = (long int *)OPENSSL_malloc(CRYPTO_num_locks() * sizeof(long));
for (i = 0; i < CRYPTO_num_locks(); i++) {
lock_count[i] = 0;
pthread_mutex_init(&(lock_cs[i]), NULL);
}
CRYPTO_THREADID_set_callback(pthreads_thread_id);
CRYPTO_set_locking_callback(pthreads_locking_callback);
}
void thread_cleanup(void)
{
int i;
CRYPTO_set_locking_callback(NULL);
BIO_printf(bio_err, "cleanup\n");
for (i = 0; i < CRYPTO_num_locks(); i++) {
pthread_mutex_destroy(&(lock_cs[i]));
BIO_printf(bio_err, "%8ld:%s\n", lock_count[i], CRYPTO_get_lock_name(i));
}
OPENSSL_free(lock_cs);
OPENSSL_free(lock_count);
BIO_printf(bio_err, "done cleanup\n");
}

Related

C++ USB communication delay

I use ftd3xx.dll to communicate with the device
The data read part and the data write part are divided into threads and used.
#include <thread>
#include <queue>
#include <array>
#include <windows.h>
using namespace std;
bool dataRead = false;
CRITICAL_SECTION sec;
queue< vector<unsigned short>> BufferQueue;
unsigned WINAPI Write(void* arg) {
int Width = 1000;
vector<unsigned short> data;
data.reserve(Width);
while (Opened)
{
while (dataRead)
{
if (BufferQueue.size() > 0) {
EnterCriticalSection(&sec);
data = BufferQueue.front();
BufferQueue.pop();
LeaveCriticalSection(&sec);
}
else
{
this_thread::sleep_for(2ms);
continue;
}
//wrtie something
}
if (!dataRead)
break;
}
_endthreadex(0);
return 0;
}
unsigned WINAPI Read(void* arg) {
int Width = 1000;
vector<unsigned short> data(Width);
BYTE* acReadBuf = new BYTE[Width];
ULONG ulBytesRead = 0;
int idx = 0;
Sleep(100);
while (dataRead)
{
ftStatus = FT_ReadPipe(ftHandle, CstReadPipeNo, acReadBuf, Width, &ulBytesRead, NULL);
if (FT_SUCCESS(ftStatus))
{
idx = 0;
for (int i = 0; i < Width; i++) {
data[i] = ((unsigned short)((unsigned short)acReadBuf[idx] | ((unsigned short)acReadBuf[idx + 1] << 8)));
idx += 2;
}
EnterCriticalSection(&sec);
if (BufferQueue.size() > 10000) {
queue< vector<unsigned short>> empty;
swap(BufferQueue, empty);
}
BufferQueue.push(data);
LeaveCriticalSection(&sec);
}
else
{
}
}
_endthreadex(0);
return 0;
}
void main() {
//start
InitializeCriticalSection(&sec);
dataRead = true;
HANDLE r_hThread = NULL;
unsigned r_threadID;
r_hThread = (HANDLE)_beginthreadex(NULL, 0, Read, NULL, 0, &r_threadID);
HANDLE w_hThread = NULL;
unsigned w_threadID;
w_hThread = (HANDLE)_beginthreadex(NULL, 0, Write, NULL, 0, &w_threadID);
//....///
//stop
dataRead = false;;
WaitForSingleObject(r_hThread, INFINITE);
WaitForSingleObject(w_hThread, INFINITE);
DeleteCriticalSection(&sec);
}
I want to queue the array directly, but first I am using it as a vector.
Importantly, data loss occurs when other programs are run or even calculators are run.
The same is true even if the device gives the data late or fast.
I would be grateful if someone could help me.

edit string in multi thread

I am newer for c++, and I know in c++0x multithreading support is poor.
But now I have to edit a string val in multi thread, I use thread_mutex to protect the val. The problem is the program always core dump when runing.
Although after re-design I find a better solution but I can't figure out why it core. So could some one told me about what happend?
The code is like below
using namespace std;
const static int kThreadSize = 48;
map<string, string> gMap;
string gStr = "";
void * func(void * data)
{
while(true)
{
printf("%s\n", gStr.c_str());
pthread_mutex_t m;
pthread_mutex_init(&m, NULL);
pthread_mutex_lock(&m);
gStr = gStr + "a";//core in this line
printf("%x\n", &gStr);//print the address
pthread_mutex_unlock(&m);
pthread_mutex_destroy(&m);
printf("%s\n", gStr.c_str());
}
}
int main()
{
pthread_t threads[kThreadSize];
for(int i = 0; i < kThreadSize; i ++)
{
pthread_create(&threads[i], NULL, &func, &gMap);
}
for(int i = 0; i < kThreadSize; i ++)
{
pthread_join(threads[i], NULL);
}
return 0;
}
EDIT:
By using the global mutex will solve the problem pointed by Mike.Here I don't paste the new source code.
My new question is I also can't understand why it will core when edit a string in multithreading. Because of COW or reference count?
As i can see there is a problem with yours Mutex, because it is create into the method func() and it make that each thread invocation of func()create a new mutex, it is happened by each threat that invokes this method.
As MikeB says, i sugest you review the thread theory but, meanwhile, try to use a unique mutex to synchronize the access to gMap, as the example shows:
using namespace std;
const static int kThreadSize = 48;
map<string, string> gMap;
string gStr = "";
pthread_mutex_t m;
void * func(void * data)
{
while(true)
{
printf("%s\n", gStr.c_str());
pthread_mutex_lock(&m);
gStr = gStr + "a";//core in this line
printf("%x\n", &gStr);//print the address
pthread_mutex_unlock(&m);
printf("%s\n", gStr.c_str());
}
}
int main()
{
pthread_mutex_init(&m, NULL);
pthread_t threads[kThreadSize];
for(int i = 0; i < kThreadSize; i ++)
{
pthread_create(&threads[i], NULL, &func, &gMap);
}
for(int i = 0; i < kThreadSize; i ++)
{
pthread_join(threads[i], NULL);
}
return 0;
}

boost::interprocess message queue Race Condition on creation?

I am trying to debug sporadic access violations that occur inside a boost::interprocess message queue. (access violation reading an address in the shared memory region).
Environment: boost 1.54, VC++2010. Occurs in both Debug & Release builds.
It always occurs on or about line 854 (in case of reception) in message_queue.hpp:
Comments were added by me
recvd_size = top_msg.len; // top_msg points to invalid location
Or line 756 (in case of sending)
BOOST_ASSERT(free_msg_hdr.priority == 0); // free_msg_hdr points to invalid location
It appears as though this is related to the message queue creation. If a message queue is created "properly" (i.e. without the possible race condition), the error never occurs.
Otherwise it might occur on timed_receive() or timed_send() on the queue at seemingly random times.
I came up with a short example that represents the problem:
Unfortunately I cannot run it on Coliru, since it requires two processes.
One has to be started without any parameters, the second with any single parameter.
After a number of runs, one of the processes will crash in message_queue.
#include <iostream>
#include <boost/interprocess/ipc/message_queue.hpp>
#include <boost/thread.hpp>
#include <boost/assert.hpp>
#include <boost/date_time.hpp>
using namespace boost::interprocess;
using namespace boost::posix_time;
using boost::posix_time::microsec_clock; // microsec_clock is ambiguous between boost::posix_time and boost::interprocess. What are the odds?
int main(int argc, wchar_t** argv)
{
while(true)
{
int proc = 0;
message_queue* queues[2] = {NULL, NULL};
std::string names[] = {"msgq0", "msgq1"};
if(1 == argc)
{
proc = 0;
message_queue::remove(names[0].c_str());
if(NULL != queues[0]) { delete queues[0]; queues[0] = NULL; }
queues[0] = new message_queue(open_or_create, names[0].c_str(), 128, 10240);
bool bRet = false;
do
{
try
{
if(NULL != queues[1]) { delete queues[1]; queues[1] = NULL; }
queues[1]=new message_queue(open_only, names[1].c_str());
bRet = true;
}
catch(const interprocess_exception&)
{
//boost::this_thread::sleep(boost::posix_time::milliseconds(2));
delete queues[1];
queues[1] = NULL;
continue;
}
}while(!bRet);
}
else
{
proc = 1;
message_queue::remove(names[1].c_str());
if(NULL != queues[1]) { delete queues[1]; queues[1] = NULL; }
queues[1] = new message_queue(open_or_create, names[1].c_str(), 128, 10240);
bool bRet = false;
do
{
try
{
if(NULL != queues[0]) { delete queues[0]; queues[0] = NULL; }
queues[0]=new message_queue(open_only, names[0].c_str());
bRet = true;
}
catch(const interprocess_exception&)
{
//boost::this_thread::sleep(boost::posix_time::milliseconds(2));
delete queues[0];
queues[0] = NULL;
continue;
}
}while(!bRet);
}
long long nCnt = 0;
for(int i = 0; i < 1; ++i)
{
if(proc)
{
std::string sOut;
sOut = "Proc1 says: Hello ProcA " + std::to_string(nCnt) + " ";
sOut.resize(10230, ':');
for(int n = 0; n < 3; ++n)
{
queues[1]->timed_send(sOut.data(), sOut.size(), 0, ptime(boost::posix_time::microsec_clock::universal_time()) + milliseconds(1));
}
bool bMessage = false;
for(int n = 0; n < 3; ++n)
{
size_t nRec; unsigned int nPrio;
std::string sIn; sIn.resize(10240);
bMessage = queues[0]->timed_receive(&sIn[0], 10240, nRec, nPrio, ptime(boost::posix_time::microsec_clock::universal_time()) + milliseconds(1));
if(bMessage)
{
sIn.resize(nRec);
//std::cout << sIn << " ";
}
}
if(bMessage)
{
//std::cout << std::endl;
}
}
else
{
std::string sOut;
sOut = "Proc0 says: Hello Procccccccdadae4325a " + std::to_string(nCnt);
sOut.resize(10240, '.');
for(int n = 0; n < 3; ++n)
{
queues[0]->timed_send(sOut.data(), sOut.size(), 0, ptime(boost::posix_time::microsec_clock::universal_time()) + milliseconds(1));
}
bool bMessage = false;
for(int n = 0; n < 3; ++n)
{
size_t nRec; unsigned int nPrio;
std::string sIn; sIn.resize(10240);
bMessage = queues[1]->timed_receive(&sIn[0], 10240, nRec, nPrio, ptime(boost::posix_time::microsec_clock::universal_time()) + milliseconds(1));
if(bMessage)
{
sIn.resize(nRec);
//std::cout << sIn << " ";
}
}
if(bMessage)
{
//std::cout << std::endl;
}
}
nCnt++;
boost::this_thread::sleep(boost::posix_time::milliseconds(10));
}
}
return 0;
}
I am still thinking I might be doing something wrong, since I cannot find anything about this problem anywhere else, and the boost libraries are normally very good.
Is there anything I might be doing wrong with the usage of the message_queue in this example?
I don't think that both processes using open_or_create is a supported idiom. Are you aware of this thread on the mailing list? I can't find more discussions so it looks to me like lifetime management wasn't eventually considered necessary to add.
Thus you'll need to synchronise the creation manually with boost::interprocess or possibly by having one of the processes retrying to open_only the queue until the other process creates it.

Determine system path for HID devices

I am searching for a way to dynamically find the system path for HID (USB) devices.
On my Ubuntu machine it's /dev/usb/hiddevX, but I suppose there are distros where hiddevices get mounted elsewhere.
To be more specific: I need this in a C program to open a HID device - this should work on every system, no matter where the devices are mounted.
Current function:
int openDevice(int vendorId, int productId) {
char devicePath[24];
unsigned int numIterations = 10, i, handle;
for (i = 0; i < numIterations; i++) {
sprintf(devicePath, "/dev/usb/hiddev%d", i);
if((handle = open(devicePath, O_RDONLY)) >= 0) {
if(isDesiredDevice(handle, vendorId, productId))
break;
close(handle);
}
}
if (i >= numIterations) {
ThrowException(Exception::TypeError(String::New("Could not find device")));
}
return handle;
}
It works well but I don't like the hardcoded /dev/usb/hiddev
Edit: It turned out that some other programmers use fallbacks to /dev/usb/hid/hiddevX and /dev/hiddevX, so I built in those fallbacks too.
Updated method:
/**
* Returns the correct handle (file descriptor) on success
*
* #param int vendorId
* #param int productId
* #return int
*/
int IO::openDevice(int vendorId, int productId) {
char devicePath[24];
const char *devicePaths[] = {
"/dev/usb/hiddev\%d",
"/dev/usb/hid/hiddev\%d",
"/dev/hiddev\%d",
NULL
};
unsigned int numIterations = 15, i, j, handle;
for (i = 0; devicePaths[i]; i++) {
for (j = 0; j < numIterations; j++) {
sprintf(devicePath, devicePaths[i], j);
if((handle = open(devicePath, O_RDONLY)) >= 0) {
if(isDesiredDevice(handle, vendorId, productId))
return handle;
close(handle);
}
}
};
ThrowException(Exception::Error(String::New("Couldn't find device!")));
return 0;
};

Embedding matplotlib in C++

I am reading a message from a socket with C++ code and am trying to plot it interactively with matplotlib, but it seems Python code will block the main thread, no matter I use show() or ion() and draw(). ion() and draw() won't block in Python.
Any idea how to plot interactively with matplotlib in C++ code?
An example would be really good.
Thanks a lot.
You may also try creating a new thread that does the call to the
blocking function, so that it does not block IO in your main program
loop. Use an array of thread objects and loop through to find an unused
one, create a thread to do the blocking calls, and have another thread
that joins them when they are completed.
This code is a quick slap-together I did to demonstrate what I mean about
using threads to get pseudo asynchronous behavior for blocking functions...
I have not compiled it or combed over it very well, it is simply to show
you how to accomplish this.
#include <pthread.h>
#include <sys/types.h>
#include <string>
#include <memory.h>
#include <malloc.h>
#define MAX_THREADS 256 // Make this as low as possible!
using namespace std;
pthread_t PTHREAD_NULL;
typedef string someTypeOrStruct;
class MyClass
{
typedef struct
{
int id;
MyClass *obj;
someTypeOrStruct input;
} thread_data;
void draw(); //Undefined in this example
bool getInput(someTypeOrStruct *); //Undefined in this example
int AsyncDraw(MyClass * obj, someTypeOrStruct &input);
static void * Joiner(MyClass * obj);
static void * DoDraw(thread_data *arg);
pthread_t thread[MAX_THREADS], JoinThread;
bool threadRunning[MAX_THREADS], StopJoinThread;
bool exitRequested;
public:
void Main();
};
bool MyClass::getInput(someTypeOrStruct *input)
{
}
void MyClass::Main()
{
exitRequested = false;
pthread_create( &JoinThread, NULL, (void *(*)(void *))MyClass::Joiner, this);
while(!exitRequested)
{
someTypeOrStruct tmpinput;
if(getInput(&tmpinput))
AsyncDraw(this, tmpinput);
}
if(JoinThread != PTHREAD_NULL)
{
StopJoinThread = true;
pthread_join(JoinThread, NULL);
}
}
void *MyClass::DoDraw(thread_data *arg)
{
if(arg == NULL) return NULL;
thread_data *data = (thread_data *) arg;
data->obj->threadRunning[data->id] = true;
// -> Do your draw here <- //
free(arg);
data->obj->threadRunning[data->id] = false; // Let the joinThread know we are done with this handle...
}
int MyClass::AsyncDraw(MyClass *obj, someTypeOrStruct &input)
{
int timeout = 10; // Adjust higher to make it try harder...
while(timeout)
{
for(int i = 0; i < MAX_THREADS; i++)
{
if(thread[i] == PTHREAD_NULL)
{
thread_data *data = (thread_data *)malloc(sizeof(thread_data));
if(data)
{
data->id = i;
data->obj = this;
data->input = input;
pthread_create( &(thread[i]), NULL,(void* (*)(void*))MyClass::DoDraw, (void *)&data);
return 1;
}
return 0;
}
}
timeout--;
}
}
void *MyClass::Joiner(MyClass * obj)
{
obj->StopJoinThread = false;
while(!obj->StopJoinThread)
{
for(int i = 0; i < MAX_THREADS; i++)
if(!obj->threadRunning[i] && obj->thread[i] != PTHREAD_NULL)
{
pthread_join(obj->thread[i], NULL);
obj->thread[i] = PTHREAD_NULL;
}
}
}
int main(int argc, char **argv)
{
MyClass base;
base.Main();
return 0;
}
This way you can continue accepting input while the draw is occurring.
~~Fixed so the above code actually compiles, make sure to add -lpthread