releasing callback thread immediately by enqueuing it and processingit on another thread.

B

bsobaid

I am working on a C# application that has C++ (unmanaged code) and
uses C++ dll. My question is not necessarily related to C# but I will
add some C# details to provide context.

I am handling an event raised by a C++ DLL. The event is supposed to
raise extremely frequently by the DLL but it seems like the event
raised by the C++ dll is blocking, by which I mean the unmanaged dll
wont raise another event until I am finished processing the current
one. I want to release the unamanged DLL's callback by introducing a
queue and processing the queue on another thread.

The complication is that there is a lots of C++ to C# communication
back and forth and that I am mainly a C# developer :(
First, unmanaged dll raises an event which is handled by my unmanaged
code. The unmanaged handler calls another static unmanaged function
which then raises a callback which is handled by the managed code. The
managed code then passes an object by reference through a static
function call to unmanaged code which populates the object passed by
reference and that concludes the processing of the event.



This is the unmanged event handler in my code for event raised by the
unmanaged dll.

RecordProcesser *m_pUpdateHandler;
MyRecords::processUpdate(Record &record)
{
m_pUpdateHandler->OnRecordUpdate (record)
}


void RecordProcesser::OnRecordUpdate(Record &record) //function called
by the event handler
{
EnterCriticalSection(obj)
Do Some processing
LeaveCriticalSEction

m_pCallback((const char *)Record.symbol(), (void*)&Record, (void*)
this); //This callback is handled in managed code

}



//THis is the managed (C#) handler of m_pCallback
private void OnRecordUpdate(string arg1, IntPtr arg2, IntPtr pThis)
{
lock (someobj)
{

//do some processing and then call an unmanaged function

GetRecord( record, obj , pThis) //This is the call to unmanaged static
function - the obj is populated by the unmanaged code and is passed as
reference here

}

}

How can I queue it all up and process it on another thread so
unmanaged dll can keep on raising the events without having to wait
for all the processing and managed-unmanaged calling I am doing here.
Someone mentioned "producer consumer queue", will it be an OK solution
in thsi context? Are there any other easier better solutions with
samples??

Thanks,
 
V

Vladyslav Lazarenko

I am working on a C# application that has C++ (unmanaged code) and
uses C++ dll. My question is not necessarily related to C# but I will
add some C# details to provide context.

I am handling an event raised by a C++ DLL. The event is supposed to
raise extremely frequently by the DLL but it seems like the event
raised by the C++ dll is blocking, by which I mean the unmanaged dll
wont raise another event until I am finished processing the  current
one. I want to release the unamanged DLL's callback by introducing a
queue and processing the queue on another thread.

The complication is that there is a lots of C++ to C# communication
back and forth and that I am mainly a C# developer :(
First, unmanaged dll raises an event which is handled by my unmanaged
code. The unmanaged handler calls another static unmanaged function
which then raises a callback which is handled by the managed code. The
managed code then passes an object by reference through a static
function call to unmanaged code which populates the object passed by
reference and that concludes the processing of the event.

This is the unmanged event handler in my code for event raised by the
unmanaged dll.

RecordProcesser *m_pUpdateHandler;
MyRecords::processUpdate(Record &record)
{
m_pUpdateHandler->OnRecordUpdate (record)

}

void RecordProcesser::OnRecordUpdate(Record &record) //function called
by the event handler
{
EnterCriticalSection(obj)
Do Some processing
LeaveCriticalSEction

m_pCallback((const char *)Record.symbol(), (void*)&Record, (void*)
this); //This callback is handled in managed code

}

//THis is the managed (C#) handler of m_pCallback
private void OnRecordUpdate(string arg1, IntPtr arg2, IntPtr pThis)
{
lock (someobj)
{

//do some processing and then call an unmanaged function

GetRecord( record, obj , pThis) //This is the call to unmanaged static
function - the obj is populated by the unmanaged code and is passed as
reference here

}
}

How can I queue it all up and process it on another thread so
unmanaged dll can keep on raising the events without having to wait
for all the processing and managed-unmanaged calling I am doing here.
Someone mentioned "producer consumer queue", will it be an OK solution
in thsi context? Are there any other easier better solutions with
samples??

Thanks,

The deadlock is not in C++ application, as I can see from your sample.
Basically, C++ code unlocks mutex by calling 'LeaveCriticalSEction'
and then calls your callback. And deadlock is caused by managed code
because the processing is not reentrant. You may solve this problem by
relying on C++ synchronization and avoid locks in managed code, or by
switching to (recursive) reentrant mutexes, or by implementing
dispatching by adding queue and worker threads. However, all these
solutions should be implemented on your side, so I don't know how C++
community can help you.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,774
Messages
2,569,598
Members
45,157
Latest member
MercedesE4
Top