On 11.04.2015 11:57, Mark Rotteveel wrote:
On 6-4-2015 12:40, Mark Rotteveel wrote:
If I add a small pause (1 to 5 milliseconds) between steps 2 and 3, the
problem doesn't occur. This seems to indicate it is a
threading/concurrency issue with invoking a callback in parallel with
the invocation of isc_que_events for a different event.
At the Java side I added a lot of synchronization already (more than I
believe should be necessary).
I have as of yet been unable to reproduce it when I strip away more of
my code, so for now it looks like the problem is on my side, or there is
a very peculiar issue related to timing/interleaving of calls to methods
and callbacks and stripping away code changes this timing.
When I look at the code in why.cpp for isc_que_events and QueCallback I
get a bit suspicious:
As far as I can tell between these statements (specifically the second
and the last):
events = attachment->queEvents(&statusWrapper, callback, length,
eventsData);
callback->setEvents(events); // should be called in case of NULL events
too
if (status.getState() & Firebird::IStatus::STATE_ERRORS)
{
return status[1];
}
*id = FB_API_HANDLE_TO_ULONG(events->getHandle());
the callback could already be triggered and have deleted events before
the id is obtained. Shouldn't it call addRef on events before setting it
to callback, and always call release at the end of the method? Or
shouldn't the mutex that is checked in the callback be locked until
isc_que_events has ended instead - like now - until the events object is
set?
Mark, can you try this patch?
Index: why.cpp
===================================================================
--- why.cpp (revision 61286)
+++ why.cpp (working copy)
@@ -2878,8 +2878,11 @@
{ }
fb_assert(events);
- events->autoReleased = true;
- events->release();
+ if (events)
+ {
+ events->autoReleased = true;
+ events->release();
+ }
}
int release()
@@ -2916,13 +2919,11 @@
RefPtr<QueCallback> callback(new QueCallback(ast, arg));
events = attachment->queEvents(&statusWrapper, callback, length, eventsData);
- callback->setEvents(events); // should be called in case of NULL events too
- if (status.getState() & Firebird::IStatus::STATE_ERRORS)
+ if (!(statusWrapper.getState() & Firebird::IStatus::STATE_ERRORS))
{
- return status[1];
+ *id = FB_API_HANDLE_TO_ULONG(events->getHandle());
}
-
- *id = FB_API_HANDLE_TO_ULONG(events->getHandle());
+ callback->setEvents(events); // should be called in case of error (i.e. NULL events) too
}
catch (const Exception& e)
{
------------------------------------------------------------------------------
BPM Camp - Free Virtual Workshop May 6th at 10am PDT/1PM EDT
Develop your own process in accordance with the BPMN 2 standard
Learn Process modeling best practices with Bonita BPM through live exercises
http://www.bonitasoft.com/be-part-of-it/events/bpm-camp-virtual- event?utm_
source=Sourceforge_BPM_Camp_5_6_15&utm_medium=email&utm_campaign=VA_SF
Firebird-Devel mailing list, web interface at
https://lists.sourceforge.net/lists/listinfo/firebird-devel