Issue Details (XML | Word | Printable)

Key: CORE-4794
Type: Bug Bug
Status: Closed Closed
Resolution: Fixed
Priority: Major Major
Assignee: Alexander Peshkov
Reporter: Mark Rotteveel
Votes: 0
Watchers: 1

If you were logged in you would be able to see more operations.
Firebird Core

isc_cancel_events returns error invalid events id (handle) (code: 335545021) if event is (no longer) queued

Created: 16/May/15 11:25 AM   Updated: 23/Sep/15 11:34 AM
Component/s: API / Client Library
Affects Version/s: 3.0 Beta 2
Fix Version/s: 3.0 Beta 2

Environment: Windows 8.1 64 bit, Firebird
Issue Links:

 Description  « Hide
Related to CORE-4756:

Cancelling an event that is not currently queued will return error 335545021 ("invalid events id (handle)"). This is a deviation from the behavior in Firebird 2.5.4 and earlier which allows this.

Sample code that reproduces this (Jaybird 3/JNA so it is close to the native API):

JnaDatabase db = factory.connect(connectionInfo);

FbClientLibrary lib = db.getClientLibrary();
ISC_STATUS[] statusVector = new ISC_STATUS[20];
SimpleEventHandler eventHandler = new SimpleEventHandler();

final JnaEventHandle eventHandle = new JnaEventHandle("TEST_EVENT_A", eventHandler, db.getEncoding());
int size = lib.isc_event_block(eventHandle.getEventBuffer(), eventHandle.getResultBuffer(), (short) 1, eventHandle.getEventNameMemory());

// Queue event
lib.isc_que_events(statusVector, db.getJnaHandle(), eventHandle.getJnaEventId(), (short) eventHandle.getSize(), eventHandle.getEventBuffer().getValue(), eventHandle.getCallback(), eventHandle.getResultBuffer().getValue());
System.out.printf("Status: %s %s%n", statusVector[0], statusVector[1]);
// Event will notify almost immediately for initial setup.

// Cancel (no event queued right now)
lib.isc_cancel_events(statusVector, db.getJnaHandle(), eventHandle.getJnaEventId());
System.out.printf("Status: %s %s%n", statusVector[0], statusVector[1]);

With the 2.5.4 fbclient.dll this prints:
Status: 1 0
Status: 1 0

Status: 1 0
Status: 1 335545021

The asynchronous nature of events makes it hard to guarantee that an event is still queued when you cancel it. As such cancelling a no longer queued event should not be considered an error (at most it should be a warning). This is also what 2.5.4 does (interface.cpp, GDS_CANCEL_EVENTS):

// If the event exists, tell the remote server to cancel it,
// and delete it from the list

Rvnt* event = find_event(port, *id);
if (event) {

 All   Comments   Change History   Subversion Commits      Sort Order: Ascending order - Click to sort in descending order
Alexander Peshkov added a comment - 18/May/15 04:12 PM
It was rather suspicious solution to silently ignore wrong ID in isc_cancel_events(). One can pass hell knows what (starting with not initialized variable) as event id into cancelation routine and be happy that he does not que for some events any more. Letting user ignore error when due to async nature of events event already happened and should not be canceled seems to be slightly better choice, but let's be backward compatible with ISC API.