8
0
mirror of https://github.com/FirebirdSQL/firebird.git synced 2025-01-23 14:03:07 +01:00

Fixed #6886: Differerent interfaces behaviour depending upon source of interface

(cherry picked from commit de15522f32)
This commit is contained in:
AlexPeshkoff 2021-08-16 20:57:55 +03:00
parent eaea0cad51
commit 11712f8203
10 changed files with 1429 additions and 324 deletions

View File

@ -137,6 +137,13 @@ namespace Firebird
r.ptr = NULL; r.ptr = NULL;
} }
T* clear() // nullify pointer w/o calling release
{
T* rc = ptr;
ptr = NULL;
return rc;
}
T* operator=(T* p) T* operator=(T* p)
{ {
return assign(p); return assign(p);

View File

@ -347,9 +347,13 @@ interface Blob : ReferenceCounted
void putSegment(Status status, uint length, void putSegment(Status status, uint length,
const void* buffer); const void* buffer);
void cancel_1(Status status);
void close_1(Status status);
int seek(Status status, int mode, int offset); // returns position
version: // 3.0.7 => 3.0.8, 4.0.0 => 4.0.1
void cancel(Status status); void cancel(Status status);
void close(Status status); void close(Status status);
int seek(Status status, int mode, int offset); // returns position
} }
interface Transaction : ReferenceCounted interface Transaction : ReferenceCounted
@ -359,14 +363,19 @@ interface Transaction : ReferenceCounted
uint bufferLength, uchar* buffer); uint bufferLength, uchar* buffer);
void prepare(Status status, void prepare(Status status,
uint msgLength, const uchar* message); uint msgLength, const uchar* message);
void commit(Status status); void commit_1(Status status);
void commitRetaining(Status status); void commitRetaining(Status status);
void rollback(Status status); void rollback_1(Status status);
void rollbackRetaining(Status status); void rollbackRetaining(Status status);
void disconnect(Status status); void disconnect_1(Status status);
Transaction join(Status status, Transaction transaction); Transaction join(Status status, Transaction transaction);
Transaction validate(Status status, Attachment attachment); Transaction validate(Status status, Attachment attachment);
Transaction enterDtc(Status status); Transaction enterDtc(Status status);
version: // 3.0.7 => 3.0.8, 4.0.0 => 4.0.1
void commit(Status status);
void rollback(Status status);
void disconnect(Status status);
} }
interface MessageMetadata : ReferenceCounted interface MessageMetadata : ReferenceCounted
@ -426,12 +435,15 @@ interface ResultSet : ReferenceCounted
boolean isEof(Status status); boolean isEof(Status status);
boolean isBof(Status status); boolean isBof(Status status);
MessageMetadata getMetadata(Status status); MessageMetadata getMetadata(Status status);
void close(Status status); void close_1(Status status);
// This item is for ISC API emulation only // This item is for ISC API emulation only
// It may be gone in future versions // It may be gone in future versions
// Please do not use it! // Please do not use it!
void setDelayedOutputFormat(Status status, MessageMetadata format); void setDelayedOutputFormat(Status status, MessageMetadata format);
version: // 3.0.7 => 3.0.8, 4.0.0 => 4.0.1
void close(Status status);
} }
interface Statement : ReferenceCounted interface Statement : ReferenceCounted
@ -472,7 +484,7 @@ interface Statement : ReferenceCounted
ResultSet openCursor(Status status, Transaction transaction, ResultSet openCursor(Status status, Transaction transaction,
MessageMetadata inMetadata, void* inBuffer, MessageMetadata outMetadata, uint flags); MessageMetadata inMetadata, void* inBuffer, MessageMetadata outMetadata, uint flags);
void setCursorName(Status status, const string name); void setCursorName(Status status, const string name);
void free(Status status); void free_1(Status status);
uint getFlags(Status status); uint getFlags(Status status);
version: // 3.0 => 4.0 version: // 3.0 => 4.0
@ -487,6 +499,9 @@ version: // 3.0 => 4.0
Pipe createPipe(Status status, Transaction transaction, MessageMetadata inMetadata, Pipe createPipe(Status status, Transaction transaction, MessageMetadata inMetadata,
void* inBuffer, MessageMetadata outMetadata, uint parLength, const uchar* par); void* inBuffer, MessageMetadata outMetadata, uint parLength, const uchar* par);
*/ */
version: // 3.0.7 => 3.0.8, 4.0.0 => 4.0.1
void free(Status status);
} }
interface Batch : ReferenceCounted interface Batch : ReferenceCounted
@ -516,6 +531,9 @@ interface Batch : ReferenceCounted
uint getBlobAlignment(Status status); uint getBlobAlignment(Status status);
MessageMetadata getMetadata(Status status); MessageMetadata getMetadata(Status status);
void setDefaultBpb(Status status, uint parLength, const uchar* par); void setDefaultBpb(Status status, uint parLength, const uchar* par);
void close_1(Status status);
version: // 4.0.0 => 4.0.1
void close(Status status); void close(Status status);
} }
@ -554,6 +572,9 @@ interface Replicator : ReferenceCounted
void process(Status status, ReplicationBatch batch); void process(Status status, ReplicationBatch batch);
*/ */
void process(Status status, uint length, const uchar* data); void process(Status status, uint length, const uchar* data);
void close_1(Status status);
version: // 4.0.0 => 4.0.1
void close(Status status); void close(Status status);
} }
@ -570,11 +591,17 @@ interface Request : ReferenceCounted
void startAndSend(Status status, Transaction tra, int level, uint msgType, void startAndSend(Status status, Transaction tra, int level, uint msgType,
uint length, const void* message); uint length, const void* message);
void unwind(Status status, int level); void unwind(Status status, int level);
void free_1(Status status);
version: // 3.0.7 => 3.0.8, 4.0.0 => 4.0.1
void free(Status status); void free(Status status);
} }
interface Events : ReferenceCounted interface Events : ReferenceCounted
{ {
void cancel_1(Status status);
version: // 3.0.7 => 3.0.8, 4.0.0 => 4.0.1
void cancel(Status status); void cancel(Status status);
} }
@ -620,8 +647,8 @@ interface Attachment : ReferenceCounted
uint length, const uchar* events); uint length, const uchar* events);
void cancelOperation(Status status, int option); void cancelOperation(Status status, int option);
void ping(Status status); void ping(Status status);
void detach(Status status); void detach_1(Status status);
void dropDatabase(Status status); void dropDatabase_1(Status status);
version: // 3.0 => 4.0 version: // 3.0 => 4.0
// Idle attachment timeout, seconds // Idle attachment timeout, seconds
@ -643,17 +670,24 @@ version: // 3.0 => 4.0
*/ */
Replicator createReplicator(Status status); Replicator createReplicator(Status status);
version: // 3.0.7 => 3.0.8, 4.0.0 => 4.0.1
void detach(Status status);
void dropDatabase(Status status);
} }
interface Service : ReferenceCounted interface Service : ReferenceCounted
{ {
void detach(Status status); void detach_1(Status status);
void query(Status status, void query(Status status,
uint sendLength, const uchar* sendItems, uint sendLength, const uchar* sendItems,
uint receiveLength, const uchar* receiveItems, uint receiveLength, const uchar* receiveItems,
uint bufferLength, uchar* buffer); uint bufferLength, uchar* buffer);
void start(Status status, void start(Status status,
uint spbLength, const uchar* spb); uint spbLength, const uchar* spb);
version: // 3.0.7 => 3.0.8, 4.0.0 => 4.0.1
void detach(Status status);
} }
interface Provider : PluginBase interface Provider : PluginBase

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -63,6 +63,8 @@ public:
void cancel(Firebird::CheckStatusWrapper* status) override; void cancel(Firebird::CheckStatusWrapper* status) override;
void close(Firebird::CheckStatusWrapper* status) override; void close(Firebird::CheckStatusWrapper* status) override;
int seek(Firebird::CheckStatusWrapper* status, int mode, int offset) override; // returns position int seek(Firebird::CheckStatusWrapper* status, int mode, int offset) override; // returns position
void cancel_1(Firebird::CheckStatusWrapper* status) override;
void close_1(Firebird::CheckStatusWrapper* status) override;
public: public:
JBlob(blb* handle, StableAttachmentPart* sa); JBlob(blb* handle, StableAttachmentPart* sa);
@ -108,6 +110,9 @@ public:
Firebird::ITransaction* join(Firebird::CheckStatusWrapper* status, Firebird::ITransaction* transaction) override; Firebird::ITransaction* join(Firebird::CheckStatusWrapper* status, Firebird::ITransaction* transaction) override;
JTransaction* validate(Firebird::CheckStatusWrapper* status, Firebird::IAttachment* testAtt) override; JTransaction* validate(Firebird::CheckStatusWrapper* status, Firebird::IAttachment* testAtt) override;
JTransaction* enterDtc(Firebird::CheckStatusWrapper* status) override; JTransaction* enterDtc(Firebird::CheckStatusWrapper* status) override;
void commit_1(Firebird::CheckStatusWrapper* status) override;
void rollback_1(Firebird::CheckStatusWrapper* status) override;
void disconnect_1(Firebird::CheckStatusWrapper* status) override;
public: public:
JTransaction(jrd_tra* handle, StableAttachmentPart* sa); JTransaction(jrd_tra* handle, StableAttachmentPart* sa);
@ -158,6 +163,7 @@ public:
FB_BOOLEAN isBof(Firebird::CheckStatusWrapper* status) override; FB_BOOLEAN isBof(Firebird::CheckStatusWrapper* status) override;
Firebird::IMessageMetadata* getMetadata(Firebird::CheckStatusWrapper* status) override; Firebird::IMessageMetadata* getMetadata(Firebird::CheckStatusWrapper* status) override;
void close(Firebird::CheckStatusWrapper* status) override; void close(Firebird::CheckStatusWrapper* status) override;
void close_1(Firebird::CheckStatusWrapper* status) override;
void setDelayedOutputFormat(Firebird::CheckStatusWrapper* status, Firebird::IMessageMetadata* format) override; void setDelayedOutputFormat(Firebird::CheckStatusWrapper* status, Firebird::IMessageMetadata* format) override;
public: public:
@ -202,6 +208,7 @@ public:
Firebird::IMessageMetadata* getMetadata(Firebird::CheckStatusWrapper* status) override; Firebird::IMessageMetadata* getMetadata(Firebird::CheckStatusWrapper* status) override;
void setDefaultBpb(Firebird::CheckStatusWrapper* status, unsigned parLength, const unsigned char* par) override; void setDefaultBpb(Firebird::CheckStatusWrapper* status, unsigned parLength, const unsigned char* par) override;
void close(Firebird::CheckStatusWrapper* status) override; void close(Firebird::CheckStatusWrapper* status) override;
void close_1(Firebird::CheckStatusWrapper* status) override;
public: public:
JBatch(DsqlBatch* handle, JStatement* aStatement, Firebird::IMessageMetadata* aMetadata); JBatch(DsqlBatch* handle, JStatement* aStatement, Firebird::IMessageMetadata* aMetadata);
@ -234,6 +241,7 @@ public:
int release() override; int release() override;
void process(Firebird::CheckStatusWrapper* status, unsigned length, const unsigned char* data) override; void process(Firebird::CheckStatusWrapper* status, unsigned length, const unsigned char* data) override;
void close(Firebird::CheckStatusWrapper* status) override; void close(Firebird::CheckStatusWrapper* status) override;
void close_1(Firebird::CheckStatusWrapper* status) override;
public: public:
JReplicator(Applier* appl, StableAttachmentPart* sa); JReplicator(Applier* appl, StableAttachmentPart* sa);
@ -270,6 +278,7 @@ public:
unsigned int itemsLength, const unsigned char* items, unsigned int itemsLength, const unsigned char* items,
unsigned int bufferLength, unsigned char* buffer) override; unsigned int bufferLength, unsigned char* buffer) override;
void free(Firebird::CheckStatusWrapper* status) override; void free(Firebird::CheckStatusWrapper* status) override;
void free_1(Firebird::CheckStatusWrapper* status) override;
ISC_UINT64 getAffectedRecords(Firebird::CheckStatusWrapper* userStatus) override; ISC_UINT64 getAffectedRecords(Firebird::CheckStatusWrapper* userStatus) override;
Firebird::IMessageMetadata* getOutputMetadata(Firebird::CheckStatusWrapper* userStatus) override; Firebird::IMessageMetadata* getOutputMetadata(Firebird::CheckStatusWrapper* userStatus) override;
Firebird::IMessageMetadata* getInputMetadata(Firebird::CheckStatusWrapper* userStatus) override; Firebird::IMessageMetadata* getInputMetadata(Firebird::CheckStatusWrapper* userStatus) override;
@ -328,6 +337,7 @@ public:
unsigned int msg_type, unsigned int length, const void* message) override; unsigned int msg_type, unsigned int length, const void* message) override;
void unwind(Firebird::CheckStatusWrapper* status, int level) override; void unwind(Firebird::CheckStatusWrapper* status, int level) override;
void free(Firebird::CheckStatusWrapper* status) override; void free(Firebird::CheckStatusWrapper* status) override;
void free_1(Firebird::CheckStatusWrapper* status) override;
public: public:
JRequest(JrdStatement* handle, StableAttachmentPart* sa); JRequest(JrdStatement* handle, StableAttachmentPart* sa);
@ -355,6 +365,7 @@ public:
// IEvents implementation // IEvents implementation
int release() override; int release() override;
void cancel(Firebird::CheckStatusWrapper* status) override; void cancel(Firebird::CheckStatusWrapper* status) override;
void cancel_1(Firebird::CheckStatusWrapper* status) override;
public: public:
JEvents(int aId, StableAttachmentPart* sa, Firebird::IEventCallback* aCallback); JEvents(int aId, StableAttachmentPart* sa, Firebird::IEventCallback* aCallback);
@ -428,6 +439,8 @@ public:
void ping(Firebird::CheckStatusWrapper* status) override; void ping(Firebird::CheckStatusWrapper* status) override;
void detach(Firebird::CheckStatusWrapper* status) override; void detach(Firebird::CheckStatusWrapper* status) override;
void dropDatabase(Firebird::CheckStatusWrapper* status) override; void dropDatabase(Firebird::CheckStatusWrapper* status) override;
void detach_1(Firebird::CheckStatusWrapper* status) override;
void dropDatabase_1(Firebird::CheckStatusWrapper* status) override;
unsigned int getIdleTimeout(Firebird::CheckStatusWrapper* status) override; unsigned int getIdleTimeout(Firebird::CheckStatusWrapper* status) override;
void setIdleTimeout(Firebird::CheckStatusWrapper* status, unsigned int timeOut) override; void setIdleTimeout(Firebird::CheckStatusWrapper* status, unsigned int timeOut) override;
@ -477,6 +490,7 @@ public:
// IService implementation // IService implementation
int release() override; int release() override;
void detach(Firebird::CheckStatusWrapper* status) override; void detach(Firebird::CheckStatusWrapper* status) override;
void detach_1(Firebird::CheckStatusWrapper* status) override;
void query(Firebird::CheckStatusWrapper* status, void query(Firebird::CheckStatusWrapper* status,
unsigned int sendLength, const unsigned char* sendItems, unsigned int sendLength, const unsigned char* sendItems,
unsigned int receiveLength, const unsigned char* receiveItems, unsigned int receiveLength, const unsigned char* receiveItems,

View File

@ -2315,7 +2315,7 @@ void JBlob::getInfo(CheckStatusWrapper* user_status,
} }
void JBlob::cancel(CheckStatusWrapper* user_status) void JBlob::cancel_1(CheckStatusWrapper* user_status)
{ {
/************************************** /**************************************
* *
@ -2331,6 +2331,14 @@ void JBlob::cancel(CheckStatusWrapper* user_status)
} }
void JBlob::cancel(CheckStatusWrapper* user_status)
{
freeEngineData(user_status);
if (user_status->isEmpty())
release();
}
void JBlob::freeEngineData(CheckStatusWrapper* user_status) void JBlob::freeEngineData(CheckStatusWrapper* user_status)
{ {
/************************************** /**************************************
@ -2369,7 +2377,7 @@ void JBlob::freeEngineData(CheckStatusWrapper* user_status)
} }
void JEvents::cancel(CheckStatusWrapper* user_status) void JEvents::cancel_1(CheckStatusWrapper* user_status)
{ {
/************************************** /**************************************
* *
@ -2385,6 +2393,14 @@ void JEvents::cancel(CheckStatusWrapper* user_status)
} }
void JEvents::cancel(CheckStatusWrapper* user_status)
{
freeEngineData(user_status);
if (user_status->isEmpty())
release();
}
void JEvents::freeEngineData(CheckStatusWrapper* user_status) void JEvents::freeEngineData(CheckStatusWrapper* user_status)
{ {
/************************************** /**************************************
@ -2466,6 +2482,14 @@ void JAttachment::cancelOperation(CheckStatusWrapper* user_status, int option)
void JBlob::close(CheckStatusWrapper* user_status) void JBlob::close(CheckStatusWrapper* user_status)
{
close_1(user_status);
if (user_status->isEmpty())
release();
}
void JBlob::close_1(CheckStatusWrapper* user_status)
{ {
/************************************** /**************************************
* *
@ -2505,6 +2529,14 @@ void JBlob::close(CheckStatusWrapper* user_status)
void JTransaction::commit(CheckStatusWrapper* user_status) void JTransaction::commit(CheckStatusWrapper* user_status)
{
commit_1(user_status);
if (user_status->isEmpty())
release();
}
void JTransaction::commit_1(CheckStatusWrapper* user_status)
{ {
/************************************** /**************************************
* *
@ -3210,7 +3242,7 @@ void JAttachment::executeDyn(CheckStatusWrapper* status, ITransaction* /*tra*/,
} }
void JAttachment::detach(CheckStatusWrapper* user_status) void JAttachment::detach_1(CheckStatusWrapper* user_status)
{ {
/************************************** /**************************************
* *
@ -3229,6 +3261,24 @@ void JAttachment::detach(CheckStatusWrapper* user_status)
} }
void JAttachment::detach(CheckStatusWrapper* user_status)
{
/**************************************
*
* g d s _ $ d e t a c h
*
**************************************
*
* Functional description
* Close down a database.
*
**************************************/
detach_1(user_status);
if (user_status->isEmpty())
release();
}
void JAttachment::freeEngineData(CheckStatusWrapper* user_status, bool forceFree) void JAttachment::freeEngineData(CheckStatusWrapper* user_status, bool forceFree)
{ {
/************************************** /**************************************
@ -3304,6 +3354,14 @@ void JAttachment::freeEngineData(CheckStatusWrapper* user_status, bool forceFree
void JAttachment::dropDatabase(CheckStatusWrapper* user_status) void JAttachment::dropDatabase(CheckStatusWrapper* user_status)
{
dropDatabase_1(user_status);
if (user_status->isEmpty())
release();
}
void JAttachment::dropDatabase_1(CheckStatusWrapper* user_status)
{ {
/************************************** /**************************************
* *
@ -3876,7 +3934,7 @@ JTransaction* JAttachment::reconnectTransaction(CheckStatusWrapper* user_status,
} }
void JRequest::free(CheckStatusWrapper* user_status) void JRequest::free_1(CheckStatusWrapper* user_status)
{ {
/************************************** /**************************************
* *
@ -3892,6 +3950,14 @@ void JRequest::free(CheckStatusWrapper* user_status)
} }
void JRequest::free(CheckStatusWrapper* user_status)
{
freeEngineData(user_status);
if (user_status->isEmpty())
release();
}
void JRequest::freeEngineData(CheckStatusWrapper* user_status) void JRequest::freeEngineData(CheckStatusWrapper* user_status)
{ {
/************************************** /**************************************
@ -4008,6 +4074,14 @@ void JTransaction::rollbackRetaining(CheckStatusWrapper* user_status)
void JTransaction::rollback(CheckStatusWrapper* user_status) void JTransaction::rollback(CheckStatusWrapper* user_status)
{
rollback_1(user_status);
if (user_status->isEmpty())
release();
}
void JTransaction::rollback_1(CheckStatusWrapper* user_status)
{ {
/************************************** /**************************************
* *
@ -4046,6 +4120,14 @@ void JTransaction::rollback(CheckStatusWrapper* user_status)
void JTransaction::disconnect(CheckStatusWrapper* user_status) void JTransaction::disconnect(CheckStatusWrapper* user_status)
{
disconnect_1(user_status);
if (user_status->isEmpty())
release();
}
void JTransaction::disconnect_1(CheckStatusWrapper* user_status)
{ {
try try
{ {
@ -4180,7 +4262,7 @@ JService* JProvider::attachServiceManager(CheckStatusWrapper* user_status, const
} }
void JService::detach(CheckStatusWrapper* user_status) void JService::detach_1(CheckStatusWrapper* user_status)
{ {
/************************************** /**************************************
* *
@ -4196,6 +4278,14 @@ void JService::detach(CheckStatusWrapper* user_status)
} }
void JService::detach(CheckStatusWrapper* user_status)
{
freeEngineData(user_status);
if (user_status->isEmpty())
release();
}
void JService::freeEngineData(CheckStatusWrapper* user_status) void JService::freeEngineData(CheckStatusWrapper* user_status)
{ {
/************************************** /**************************************
@ -5361,20 +5451,30 @@ void JResultSet::freeEngineData(CheckStatusWrapper* user_status)
successful_completion(user_status); successful_completion(user_status);
} }
StableAttachmentPart* JResultSet::getAttachment() StableAttachmentPart* JResultSet::getAttachment()
{ {
return statement->getAttachment(); return statement->getAttachment();
} }
IMessageMetadata* JResultSet::getMetadata(CheckStatusWrapper* user_status) IMessageMetadata* JResultSet::getMetadata(CheckStatusWrapper* user_status)
{ {
return statement->getOutputMetadata(user_status); return statement->getOutputMetadata(user_status);
} }
void JResultSet::close_1(CheckStatusWrapper* user_status)
{
freeEngineData(user_status);
}
void JResultSet::close(CheckStatusWrapper* user_status) void JResultSet::close(CheckStatusWrapper* user_status)
{ {
freeEngineData(user_status); freeEngineData(user_status);
if (user_status->isEmpty())
release();
} }
@ -5406,9 +5506,17 @@ void JStatement::freeEngineData(CheckStatusWrapper* user_status)
} }
void JStatement::free_1(CheckStatusWrapper* user_status)
{
freeEngineData(user_status);
}
void JStatement::free(CheckStatusWrapper* user_status) void JStatement::free(CheckStatusWrapper* user_status)
{ {
freeEngineData(user_status); freeEngineData(user_status);
if (user_status->isEmpty())
release();
} }
@ -5890,9 +5998,17 @@ int JBatch::release()
} }
void JBatch::close_1(CheckStatusWrapper* user_status)
{
freeEngineData(user_status);
}
void JBatch::close(CheckStatusWrapper* user_status) void JBatch::close(CheckStatusWrapper* user_status)
{ {
freeEngineData(user_status); freeEngineData(user_status);
if (user_status->isEmpty())
release();
} }
@ -6296,9 +6412,17 @@ void JReplicator::process(CheckStatusWrapper* status, unsigned length, const UCH
} }
void JReplicator::close_1(CheckStatusWrapper* user_status)
{
freeEngineData(user_status);
}
void JReplicator::close(CheckStatusWrapper* user_status) void JReplicator::close(CheckStatusWrapper* user_status)
{ {
freeEngineData(user_status); freeEngineData(user_status);
if (user_status->isEmpty())
release();
} }

View File

@ -173,6 +173,8 @@ public:
void cancel(CheckStatusWrapper* status) override; void cancel(CheckStatusWrapper* status) override;
void close(CheckStatusWrapper* status) override; void close(CheckStatusWrapper* status) override;
int seek(CheckStatusWrapper* status, int mode, int offset) override; // returns position int seek(CheckStatusWrapper* status, int mode, int offset) override; // returns position
void cancel_1(Firebird::CheckStatusWrapper* status) override;
void close_1(Firebird::CheckStatusWrapper* status) override;
public: public:
explicit Blob(Rbl* handle) explicit Blob(Rbl* handle)
@ -223,6 +225,9 @@ public:
ITransaction* join(CheckStatusWrapper* status, ITransaction* tra) override; ITransaction* join(CheckStatusWrapper* status, ITransaction* tra) override;
Transaction* validate(CheckStatusWrapper* status, IAttachment* attachment) override; Transaction* validate(CheckStatusWrapper* status, IAttachment* attachment) override;
Transaction* enterDtc(CheckStatusWrapper* status) override; Transaction* enterDtc(CheckStatusWrapper* status) override;
void commit_1(Firebird::CheckStatusWrapper* status) override;
void rollback_1(Firebird::CheckStatusWrapper* status) override;
void disconnect_1(Firebird::CheckStatusWrapper* status) override;
public: public:
Transaction(Rtr* handle, Attachment* a) Transaction(Rtr* handle, Attachment* a)
@ -285,6 +290,7 @@ public:
FB_BOOLEAN isBof(CheckStatusWrapper* status) override; FB_BOOLEAN isBof(CheckStatusWrapper* status) override;
IMessageMetadata* getMetadata(CheckStatusWrapper* status) override; IMessageMetadata* getMetadata(CheckStatusWrapper* status) override;
void close(CheckStatusWrapper* status) override; void close(CheckStatusWrapper* status) override;
void close_1(CheckStatusWrapper* status) override;
void setDelayedOutputFormat(CheckStatusWrapper* status, IMessageMetadata* format) override; void setDelayedOutputFormat(CheckStatusWrapper* status, IMessageMetadata* format) override;
ResultSet(Statement* s, IMessageMetadata* outFmt) ResultSet(Statement* s, IMessageMetadata* outFmt)
@ -328,7 +334,7 @@ public:
Batch(Statement* s, IMessageMetadata* inFmt, unsigned parLength, const unsigned char* par); Batch(Statement* s, IMessageMetadata* inFmt, unsigned parLength, const unsigned char* par);
// IResultSet implementation // IBatch implementation
int release() override; int release() override;
void add(Firebird::CheckStatusWrapper* status, unsigned count, const void* inBuffer) override; void add(Firebird::CheckStatusWrapper* status, unsigned count, const void* inBuffer) override;
void addBlob(Firebird::CheckStatusWrapper* status, unsigned length, const void* inBuffer, ISC_QUAD* blobId, void addBlob(Firebird::CheckStatusWrapper* status, unsigned length, const void* inBuffer, ISC_QUAD* blobId,
@ -342,6 +348,7 @@ public:
void setDefaultBpb(Firebird::CheckStatusWrapper* status, unsigned parLength, const unsigned char* par) override; void setDefaultBpb(Firebird::CheckStatusWrapper* status, unsigned parLength, const unsigned char* par) override;
Firebird::IMessageMetadata* getMetadata(Firebird::CheckStatusWrapper* status) override; Firebird::IMessageMetadata* getMetadata(Firebird::CheckStatusWrapper* status) override;
void close(Firebird::CheckStatusWrapper* status) override; void close(Firebird::CheckStatusWrapper* status) override;
void close_1(Firebird::CheckStatusWrapper* status) override;
private: private:
void freeClientData(CheckStatusWrapper* status, bool force = false); void freeClientData(CheckStatusWrapper* status, bool force = false);
@ -569,6 +576,7 @@ public:
int release() override; int release() override;
void process(CheckStatusWrapper* status, unsigned length, const unsigned char* data) override; void process(CheckStatusWrapper* status, unsigned length, const unsigned char* data) override;
void close(CheckStatusWrapper* status) override; void close(CheckStatusWrapper* status) override;
void close_1(CheckStatusWrapper* status) override;
explicit Replicator(Attachment* att) : attachment(att) explicit Replicator(Attachment* att) : attachment(att)
{} {}
@ -616,6 +624,7 @@ public:
unsigned int flags) override; unsigned int flags) override;
void setCursorName(CheckStatusWrapper* status, const char* name) override; void setCursorName(CheckStatusWrapper* status, const char* name) override;
void free(CheckStatusWrapper* status) override; void free(CheckStatusWrapper* status) override;
void free_1(CheckStatusWrapper* status) override;
unsigned getFlags(CheckStatusWrapper* status) override; unsigned getFlags(CheckStatusWrapper* status) override;
unsigned int getTimeout(CheckStatusWrapper* status) override unsigned int getTimeout(CheckStatusWrapper* status) override
@ -716,6 +725,7 @@ public:
unsigned int length, const void* message) override; unsigned int length, const void* message) override;
void unwind(CheckStatusWrapper* status, int level) override; void unwind(CheckStatusWrapper* status, int level) override;
void free(CheckStatusWrapper* status) override; void free(CheckStatusWrapper* status) override;
void free_1(CheckStatusWrapper* status) override;
public: public:
Request(Rrq* handle, Attachment* a) Request(Rrq* handle, Attachment* a)
@ -753,6 +763,7 @@ public:
// IEvents implementation // IEvents implementation
int release() override; int release() override;
void cancel(CheckStatusWrapper* status) override; void cancel(CheckStatusWrapper* status) override;
void cancel_1(CheckStatusWrapper* status) override;
public: public:
Events(Rvnt* handle) Events(Rvnt* handle)
@ -834,6 +845,8 @@ public:
void ping(CheckStatusWrapper* status) override; void ping(CheckStatusWrapper* status) override;
void detach(CheckStatusWrapper* status) override; void detach(CheckStatusWrapper* status) override;
void dropDatabase(CheckStatusWrapper* status) override; void dropDatabase(CheckStatusWrapper* status) override;
void detach_1(Firebird::CheckStatusWrapper* status) override;
void dropDatabase_1(Firebird::CheckStatusWrapper* status) override;
unsigned int getIdleTimeout(CheckStatusWrapper* status) override; unsigned int getIdleTimeout(CheckStatusWrapper* status) override;
void setIdleTimeout(CheckStatusWrapper* status, unsigned int timeOut) override; void setIdleTimeout(CheckStatusWrapper* status, unsigned int timeOut) override;
@ -898,6 +911,7 @@ public:
// IService implementation // IService implementation
int release() override; int release() override;
void detach(CheckStatusWrapper* status) override; void detach(CheckStatusWrapper* status) override;
void detach_1(CheckStatusWrapper* status) override;
void query(CheckStatusWrapper* status, void query(CheckStatusWrapper* status,
unsigned int sendLength, const unsigned char* sendItems, unsigned int sendLength, const unsigned char* sendItems,
unsigned int receiveLength, const unsigned char* receiveItems, unsigned int receiveLength, const unsigned char* receiveItems,
@ -1278,7 +1292,7 @@ void Blob::freeClientData(CheckStatusWrapper* status, bool force)
} }
void Blob::cancel(CheckStatusWrapper* status) void Blob::cancel_1(CheckStatusWrapper* status)
{ {
/************************************** /**************************************
* *
@ -1295,7 +1309,15 @@ void Blob::cancel(CheckStatusWrapper* status)
} }
void Blob::close(CheckStatusWrapper* status) void Blob::cancel(CheckStatusWrapper* status)
{
cancel_1(status);
if (status->isEmpty())
release();
}
void Blob::close_1(CheckStatusWrapper* status)
{ {
/************************************** /**************************************
* *
@ -1334,6 +1356,14 @@ void Blob::close(CheckStatusWrapper* status)
} }
void Blob::close(CheckStatusWrapper* status)
{
close_1(status);
if (status->isEmpty())
release();
}
void Events::freeClientData(CheckStatusWrapper* status, bool force) void Events::freeClientData(CheckStatusWrapper* status, bool force)
{ {
/************************************** /**************************************
@ -1416,7 +1446,7 @@ void Events::freeClientData(CheckStatusWrapper* status, bool force)
} }
void Events::cancel(CheckStatusWrapper* status) void Events::cancel_1(CheckStatusWrapper* status)
{ {
/************************************** /**************************************
* *
@ -1433,7 +1463,15 @@ void Events::cancel(CheckStatusWrapper* status)
} }
void Transaction::commit(CheckStatusWrapper* status) void Events::cancel(CheckStatusWrapper* status)
{
cancel_1(status);
if (status->isEmpty())
release();
}
void Transaction::commit_1(CheckStatusWrapper* status)
{ {
/************************************** /**************************************
* *
@ -1468,6 +1506,14 @@ void Transaction::commit(CheckStatusWrapper* status)
} }
void Transaction::commit(CheckStatusWrapper* status)
{
commit_1(status);
if (status->isEmpty())
release();
}
void Transaction::commitRetaining(CheckStatusWrapper* status) void Transaction::commitRetaining(CheckStatusWrapper* status)
{ {
/************************************** /**************************************
@ -1987,7 +2033,7 @@ void Attachment::freeClientData(CheckStatusWrapper* status, bool force)
} }
void Attachment::detach(CheckStatusWrapper* status) void Attachment::detach_1(CheckStatusWrapper* status)
{ {
/************************************** /**************************************
* *
@ -2004,7 +2050,15 @@ void Attachment::detach(CheckStatusWrapper* status)
} }
void Attachment::dropDatabase(CheckStatusWrapper* status) void Attachment::detach(CheckStatusWrapper* status)
{
detach_1(status);
if (status->isEmpty())
release();
}
void Attachment::dropDatabase_1(CheckStatusWrapper* status)
{ {
/************************************** /**************************************
* *
@ -2062,6 +2116,14 @@ void Attachment::dropDatabase(CheckStatusWrapper* status)
} }
void Attachment::dropDatabase(CheckStatusWrapper* status)
{
dropDatabase_1(status);
if (status->isEmpty())
release();
}
SLONG Attachment::getSingleInfo(CheckStatusWrapper* status, UCHAR infoItem) SLONG Attachment::getSingleInfo(CheckStatusWrapper* status, UCHAR infoItem)
{ {
UCHAR buff[16]; UCHAR buff[16];
@ -2885,6 +2947,14 @@ void Batch::close(CheckStatusWrapper* status)
} }
void Batch::close_1(CheckStatusWrapper* status)
{
close_1(status);
if (status->isEmpty())
release();
}
void Batch::releaseStatement() void Batch::releaseStatement()
{ {
if (tmpStatement) if (tmpStatement)
@ -2976,6 +3046,14 @@ void Replicator::close(CheckStatusWrapper* status)
} }
void Replicator::close_1(CheckStatusWrapper* status)
{
close_1(status);
if (status->isEmpty())
release();
}
void Replicator::freeClientData(CheckStatusWrapper* status, bool force) void Replicator::freeClientData(CheckStatusWrapper* status, bool force)
{ {
try try
@ -3626,7 +3704,7 @@ void Statement::freeClientData(CheckStatusWrapper* status, bool force)
} }
void Statement::free(CheckStatusWrapper* status) void Statement::free_1(CheckStatusWrapper* status)
{ {
/************************************** /**************************************
* *
@ -3644,6 +3722,14 @@ void Statement::free(CheckStatusWrapper* status)
} }
void Statement::free(CheckStatusWrapper* status)
{
free_1(status);
if (status->isEmpty())
release();
}
Statement* Attachment::createStatement(CheckStatusWrapper* status, unsigned dialect) Statement* Attachment::createStatement(CheckStatusWrapper* status, unsigned dialect)
{ {
reset(status); reset(status);
@ -4631,7 +4717,7 @@ void ResultSet::freeClientData(CheckStatusWrapper* status, bool force)
} }
void ResultSet::close(CheckStatusWrapper* status) void ResultSet::close_1(CheckStatusWrapper* status)
{ {
/************************************** /**************************************
* *
@ -4649,6 +4735,25 @@ void ResultSet::close(CheckStatusWrapper* status)
} }
void ResultSet::close(CheckStatusWrapper* status)
{
/**************************************
*
* d s q l _ f r e e _ s t a t e m e n t
*
**************************************
*
* Functional description
* Close SQL cursor
*
**************************************/
close_1(status);
if (status->isEmpty())
release();
}
void ResultSet::releaseStatement() void ResultSet::releaseStatement()
{ {
if (tmpStatement) if (tmpStatement)
@ -5532,7 +5637,7 @@ void Request::freeClientData(CheckStatusWrapper* status, bool force)
} }
void Request::free(CheckStatusWrapper* status) void Request::free_1(CheckStatusWrapper* status)
{ {
/************************************** /**************************************
* *
@ -5549,6 +5654,14 @@ void Request::free(CheckStatusWrapper* status)
} }
void Request::free(CheckStatusWrapper* status)
{
free_1(status);
if (status->isEmpty())
release();
}
void Request::getInfo(CheckStatusWrapper* status, int level, void Request::getInfo(CheckStatusWrapper* status, int level,
unsigned int itemsLength, const unsigned char* items, unsigned int itemsLength, const unsigned char* items,
unsigned int bufferLength, unsigned char* buffer) unsigned int bufferLength, unsigned char* buffer)
@ -5716,7 +5829,7 @@ void Transaction::freeClientData(CheckStatusWrapper* status, bool force)
} }
void Transaction::rollback(CheckStatusWrapper* status) void Transaction::rollback_1(CheckStatusWrapper* status)
{ {
/************************************** /**************************************
* *
@ -5733,7 +5846,15 @@ void Transaction::rollback(CheckStatusWrapper* status)
} }
void Transaction::disconnect(CheckStatusWrapper* status) void Transaction::rollback(CheckStatusWrapper* status)
{
rollback_1(status);
if (status->isEmpty())
release();
}
void Transaction::disconnect_1(CheckStatusWrapper* status)
{ {
try try
{ {
@ -5753,6 +5874,15 @@ void Transaction::disconnect(CheckStatusWrapper* status)
} }
void Transaction::disconnect(CheckStatusWrapper* status)
{
disconnect_1(status);
if (status->isEmpty())
release();
}
int Blob::seek(CheckStatusWrapper* status, int mode, int offset) int Blob::seek(CheckStatusWrapper* status, int mode, int offset)
{ {
/************************************** /**************************************
@ -6004,7 +6134,7 @@ void Service::freeClientData(CheckStatusWrapper* status, bool force)
} }
void Service::detach(CheckStatusWrapper* status) void Service::detach_1(CheckStatusWrapper* status)
{ {
/************************************** /**************************************
* *
@ -6021,6 +6151,14 @@ void Service::detach(CheckStatusWrapper* status)
} }
void Service::detach(CheckStatusWrapper* status)
{
detach_1(status);
if (status->isEmpty())
release();
}
void Service::query(CheckStatusWrapper* status, void Service::query(CheckStatusWrapper* status,
unsigned int sendLength, const unsigned char* sendItems, unsigned int sendLength, const unsigned char* sendItems,
unsigned int receiveLength, const unsigned char* receiveItems, unsigned int receiveLength, const unsigned char* receiveItems,

View File

@ -61,6 +61,9 @@ public:
DTransaction* join(CheckStatusWrapper* status, ITransaction* transaction); DTransaction* join(CheckStatusWrapper* status, ITransaction* transaction);
ITransaction* validate(CheckStatusWrapper* status, IAttachment* attachment); ITransaction* validate(CheckStatusWrapper* status, IAttachment* attachment);
DTransaction* enterDtc(CheckStatusWrapper* status); DTransaction* enterDtc(CheckStatusWrapper* status);
void commit_1(CheckStatusWrapper* status);
void rollback_1(CheckStatusWrapper* status);
void disconnect_1(CheckStatusWrapper* status);
private: private:
typedef HalfStaticArray<ITransaction*, 8> SubArray; typedef HalfStaticArray<ITransaction*, 8> SubArray;
@ -97,7 +100,7 @@ bool DTransaction::buildPrepareInfo(CheckStatusWrapper* status, TdrBuffer& tdr,
// limit MAX_SSHORT is chosen cause for old API larger buffer cause problems // limit MAX_SSHORT is chosen cause for old API larger buffer cause problems
UCHAR* buf = bigBuffer.getBuffer(MAX_SSHORT); UCHAR* buf = bigBuffer.getBuffer(MAX_SSHORT);
from->getInfo(status, sizeof(PREPARE_TR_INFO), PREPARE_TR_INFO, bigBuffer.getCount(), buf); from->getInfo(status, sizeof(PREPARE_TR_INFO), PREPARE_TR_INFO, bigBuffer.getCount(), buf);
if (status->getState() & Firebird::IStatus::STATE_ERRORS) if (status->getState() & IStatus::STATE_ERRORS)
return false; return false;
UCHAR* const end = bigBuffer.end(); UCHAR* const end = bigBuffer.end();
@ -178,7 +181,7 @@ void DTransaction::getInfo(CheckStatusWrapper* status,
if (sub[i]) if (sub[i])
{ {
sub[i]->getInfo(status, itemsLength, items, bufferLength, buffer); sub[i]->getInfo(status, itemsLength, items, bufferLength, buffer);
if (status->getState() & Firebird::IStatus::STATE_ERRORS) if (status->getState() & IStatus::STATE_ERRORS)
{ {
return; return;
} }
@ -232,7 +235,7 @@ void DTransaction::prepare(CheckStatusWrapper* status,
{ {
sub[i]->prepare(status, msgLength, message); sub[i]->prepare(status, msgLength, message);
if (status->getState() & Firebird::IStatus::STATE_ERRORS) if (status->getState() & IStatus::STATE_ERRORS)
return; return;
} }
} }
@ -252,7 +255,7 @@ void DTransaction::commit(CheckStatusWrapper* status)
status->init(); status->init();
prepare(status, 0, NULL); prepare(status, 0, NULL);
if (status->getState() & Firebird::IStatus::STATE_ERRORS) if (status->getState() & IStatus::STATE_ERRORS)
{ {
return; return;
} }
@ -265,7 +268,7 @@ void DTransaction::commit(CheckStatusWrapper* status)
if (sub[i]) if (sub[i])
{ {
sub[i]->commit(status); sub[i]->commit(status);
if (status->getState() & Firebird::IStatus::STATE_ERRORS) if (status->getState() & IStatus::STATE_ERRORS)
return; return;
sub[i] = NULL; sub[i] = NULL;
@ -295,12 +298,10 @@ void DTransaction::commitRetaining(CheckStatusWrapper* status)
if (sub[i]) if (sub[i])
{ {
sub[i]->commitRetaining(status); sub[i]->commitRetaining(status);
if (status->getState() & Firebird::IStatus::STATE_ERRORS) if (status->getState() & IStatus::STATE_ERRORS)
return; return;
} }
} }
limbo = true; // ASF: why do retaining marks limbo?
} }
catch (const Exception& ex) catch (const Exception& ex)
{ {
@ -322,7 +323,7 @@ void DTransaction::rollback(CheckStatusWrapper* status)
if (sub[i]) if (sub[i])
{ {
sub[i]->rollback(status); sub[i]->rollback(status);
if (status->getState() & Firebird::IStatus::STATE_ERRORS) if (status->getState() & IStatus::STATE_ERRORS)
return; return;
sub[i] = NULL; sub[i] = NULL;
@ -349,12 +350,10 @@ void DTransaction::rollbackRetaining(CheckStatusWrapper* status)
if (sub[i]) if (sub[i])
{ {
sub[i]->rollbackRetaining(status); sub[i]->rollbackRetaining(status);
if (status->getState() & Firebird::IStatus::STATE_ERRORS) if (status->getState() & IStatus::STATE_ERRORS)
return; return;
} }
} }
limbo = true; // ASF: why do retaining marks limbo?
} }
catch (const Exception& ex) catch (const Exception& ex)
{ {
@ -378,7 +377,7 @@ void DTransaction::disconnect(CheckStatusWrapper* status)
if (sub[i]) if (sub[i])
{ {
sub[i]->disconnect(status); sub[i]->disconnect(status);
if (status->getState() & Firebird::IStatus::STATE_ERRORS) if (status->getState() & IStatus::STATE_ERRORS)
return; return;
sub[i] = NULL; sub[i] = NULL;
@ -391,6 +390,22 @@ void DTransaction::disconnect(CheckStatusWrapper* status)
} }
} }
void DTransaction::commit_1(CheckStatusWrapper* status)
{
commit(status);
}
void DTransaction::rollback_1(CheckStatusWrapper* status)
{
rollback(status);
}
void DTransaction::disconnect_1(CheckStatusWrapper* status)
{
disconnect(status);
}
// To do: check the maximum allowed dbs in a two phase commit. // To do: check the maximum allowed dbs in a two phase commit.
// Q: what is the maximum? // Q: what is the maximum?
DTransaction* DTransaction::join(CheckStatusWrapper* status, ITransaction* transaction) DTransaction* DTransaction::join(CheckStatusWrapper* status, ITransaction* transaction)
@ -528,7 +543,7 @@ YTransaction* DtcStart::start(CheckStatusWrapper* status)
RefPtr<DTransaction> dtransaction(FB_NEW DTransaction); RefPtr<DTransaction> dtransaction(FB_NEW DTransaction);
unsigned cnt = components.getCount(); unsigned cnt = components.getCount();
if (status->getState() & Firebird::IStatus::STATE_ERRORS) if (status->getState() & IStatus::STATE_ERRORS)
status_exception::raise(status); status_exception::raise(status);
if (cnt == 0) if (cnt == 0)
(Arg::Gds(isc_random) << "No attachments to start distributed transaction provided").raise(); (Arg::Gds(isc_random) << "No attachments to start distributed transaction provided").raise();
@ -536,11 +551,11 @@ YTransaction* DtcStart::start(CheckStatusWrapper* status)
for (unsigned i = 0; i < cnt; ++i) for (unsigned i = 0; i < cnt; ++i)
{ {
ITransaction* started = components[i].att->startTransaction(status, components[i].tpbLen, components[i].tpb); ITransaction* started = components[i].att->startTransaction(status, components[i].tpbLen, components[i].tpb);
if (status->getState() & Firebird::IStatus::STATE_ERRORS) if (status->getState() & IStatus::STATE_ERRORS)
status_exception::raise(status); status_exception::raise(status);
dtransaction->join(status, started); dtransaction->join(status, started);
if (status->getState() & Firebird::IStatus::STATE_ERRORS) if (status->getState() & IStatus::STATE_ERRORS)
{ {
started->release(); started->release();
status_exception::raise(status); status_exception::raise(status);
@ -570,12 +585,12 @@ YTransaction* Dtc::join(CheckStatusWrapper* status, ITransaction* one, ITransact
RefPtr<DTransaction> dtransaction(FB_NEW DTransaction); RefPtr<DTransaction> dtransaction(FB_NEW DTransaction);
dtransaction->join(status, one); dtransaction->join(status, one);
if (status->getState() & Firebird::IStatus::STATE_ERRORS) if (status->getState() & IStatus::STATE_ERRORS)
return NULL; return NULL;
dtransaction->join(status, two); dtransaction->join(status, two);
/* We must not return NULL - first transaction is available only inside dtransaction /* We must not return NULL - first transaction is available only inside dtransaction
if (status->getState() & Firebird::IStatus::STATE_ERRORS) if (status->getState() & IStatus::STATE_ERRORS)
return NULL; return NULL;
*/ */

View File

@ -133,6 +133,7 @@ public:
typedef YAttachment YRef; typedef YAttachment YRef;
static const unsigned DF_RELEASE = 0x1; static const unsigned DF_RELEASE = 0x1;
static const unsigned DF_KEEP_NEXT = 0x2;
explicit YHelper(NextInterface* aNext, const char* m = NULL) explicit YHelper(NextInterface* aNext, const char* m = NULL)
: :
@ -160,7 +161,10 @@ public:
void destroy2(unsigned dstrFlags) void destroy2(unsigned dstrFlags)
{ {
next = NULL; if (dstrFlags & DF_KEEP_NEXT)
next.clear();
else
next = NULL;
if (dstrFlags & DF_RELEASE) if (dstrFlags & DF_RELEASE)
{ {
@ -213,6 +217,7 @@ public:
// IEvents implementation // IEvents implementation
void cancel(Firebird::CheckStatusWrapper* status); void cancel(Firebird::CheckStatusWrapper* status);
void cancel_1(Firebird::CheckStatusWrapper* status);
public: public:
AtomicAttPtr attachment; AtomicAttPtr attachment;
@ -245,6 +250,7 @@ public:
unsigned int msgType, unsigned int length, const void* message); unsigned int msgType, unsigned int length, const void* message);
void unwind(Firebird::CheckStatusWrapper* status, int level); void unwind(Firebird::CheckStatusWrapper* status, int level);
void free(Firebird::CheckStatusWrapper* status); void free(Firebird::CheckStatusWrapper* status);
void free_1(Firebird::CheckStatusWrapper* status);
public: public:
AtomicAttPtr attachment; AtomicAttPtr attachment;
@ -275,6 +281,9 @@ public:
Firebird::ITransaction* join(Firebird::CheckStatusWrapper* status, Firebird::ITransaction* transaction); Firebird::ITransaction* join(Firebird::CheckStatusWrapper* status, Firebird::ITransaction* transaction);
Firebird::ITransaction* validate(Firebird::CheckStatusWrapper* status, Firebird::IAttachment* testAtt); Firebird::ITransaction* validate(Firebird::CheckStatusWrapper* status, Firebird::IAttachment* testAtt);
YTransaction* enterDtc(Firebird::CheckStatusWrapper* status); YTransaction* enterDtc(Firebird::CheckStatusWrapper* status);
void commit_1(Firebird::CheckStatusWrapper* status);
void rollback_1(Firebird::CheckStatusWrapper* status);
void disconnect_1(Firebird::CheckStatusWrapper* status);
void addCleanupHandler(Firebird::CheckStatusWrapper* status, CleanupCallback* callback); void addCleanupHandler(Firebird::CheckStatusWrapper* status, CleanupCallback* callback);
void selfCheck(); void selfCheck();
@ -324,6 +333,8 @@ public:
void cancel(Firebird::CheckStatusWrapper* status); void cancel(Firebird::CheckStatusWrapper* status);
void close(Firebird::CheckStatusWrapper* status); void close(Firebird::CheckStatusWrapper* status);
int seek(Firebird::CheckStatusWrapper* status, int mode, int offset); int seek(Firebird::CheckStatusWrapper* status, int mode, int offset);
void cancel_1(Firebird::CheckStatusWrapper* status);
void close_1(Firebird::CheckStatusWrapper* status);
public: public:
AtomicAttPtr attachment; AtomicAttPtr attachment;
@ -353,6 +364,7 @@ public:
FB_BOOLEAN isBof(Firebird::CheckStatusWrapper* status); FB_BOOLEAN isBof(Firebird::CheckStatusWrapper* status);
Firebird::IMessageMetadata* getMetadata(Firebird::CheckStatusWrapper* status); Firebird::IMessageMetadata* getMetadata(Firebird::CheckStatusWrapper* status);
void close(Firebird::CheckStatusWrapper* status); void close(Firebird::CheckStatusWrapper* status);
void close_1(Firebird::CheckStatusWrapper* status);
void setDelayedOutputFormat(Firebird::CheckStatusWrapper* status, Firebird::IMessageMetadata* format); void setDelayedOutputFormat(Firebird::CheckStatusWrapper* status, Firebird::IMessageMetadata* format);
public: public:
@ -384,6 +396,7 @@ public:
void cancel(Firebird::CheckStatusWrapper* status); void cancel(Firebird::CheckStatusWrapper* status);
void setDefaultBpb(Firebird::CheckStatusWrapper* status, unsigned parLength, const unsigned char* par); void setDefaultBpb(Firebird::CheckStatusWrapper* status, unsigned parLength, const unsigned char* par);
void close(Firebird::CheckStatusWrapper* status); void close(Firebird::CheckStatusWrapper* status);
void close_1(Firebird::CheckStatusWrapper* status);
public: public:
AtomicAttPtr attachment; AtomicAttPtr attachment;
@ -403,6 +416,7 @@ public:
// IReplicator implementation // IReplicator implementation
void process(Firebird::CheckStatusWrapper* status, unsigned length, const unsigned char* data); void process(Firebird::CheckStatusWrapper* status, unsigned length, const unsigned char* data);
void close(Firebird::CheckStatusWrapper* status); void close(Firebird::CheckStatusWrapper* status);
void close_1(Firebird::CheckStatusWrapper* status);
public: public:
AtomicAttPtr attachment; AtomicAttPtr attachment;
@ -451,6 +465,7 @@ public:
unsigned int flags); unsigned int flags);
void setCursorName(Firebird::CheckStatusWrapper* status, const char* name); void setCursorName(Firebird::CheckStatusWrapper* status, const char* name);
void free(Firebird::CheckStatusWrapper* status); void free(Firebird::CheckStatusWrapper* status);
void free_1(Firebird::CheckStatusWrapper* status);
unsigned getFlags(Firebird::CheckStatusWrapper* status); unsigned getFlags(Firebird::CheckStatusWrapper* status);
unsigned int getTimeout(Firebird::CheckStatusWrapper* status); unsigned int getTimeout(Firebird::CheckStatusWrapper* status);
@ -540,6 +555,8 @@ public:
void ping(Firebird::CheckStatusWrapper* status); void ping(Firebird::CheckStatusWrapper* status);
void detach(Firebird::CheckStatusWrapper* status); void detach(Firebird::CheckStatusWrapper* status);
void dropDatabase(Firebird::CheckStatusWrapper* status); void dropDatabase(Firebird::CheckStatusWrapper* status);
void detach_1(Firebird::CheckStatusWrapper* status);
void dropDatabase_1(Firebird::CheckStatusWrapper* status);
void addCleanupHandler(Firebird::CheckStatusWrapper* status, CleanupCallback* callback); void addCleanupHandler(Firebird::CheckStatusWrapper* status, CleanupCallback* callback);
YTransaction* getTransaction(Firebird::ITransaction* tra); YTransaction* getTransaction(Firebird::ITransaction* tra);
@ -587,6 +604,7 @@ public:
// IService implementation // IService implementation
void detach(Firebird::CheckStatusWrapper* status); void detach(Firebird::CheckStatusWrapper* status);
void detach_1(Firebird::CheckStatusWrapper* status);
void query(Firebird::CheckStatusWrapper* status, void query(Firebird::CheckStatusWrapper* status,
unsigned int sendLength, const unsigned char* sendItems, unsigned int sendLength, const unsigned char* sendItems,
unsigned int receiveLength, const unsigned char* receiveItems, unsigned int receiveLength, const unsigned char* receiveItems,

View File

@ -75,6 +75,8 @@
#include <signal.h> #include <signal.h>
#endif #endif
#include <functional>
using namespace Firebird; using namespace Firebird;
using namespace Why; using namespace Why;
@ -1324,6 +1326,27 @@ namespace Why
bool shutdownMode; bool shutdownMode;
}; };
template <class Y>
void done(CheckStatusWrapper* status, YEntry<Y>& entry, Y* y, std::function<void()> newClose, std::function<void()> oldClose)
{
if (entry.next())
newClose();
if (!(status->getState() & IStatus::STATE_ERRORS))
y->destroy(Y::DF_RELEASE | Y::DF_KEEP_NEXT);
else if (status->getErrors()[1] == isc_wish_list)
{
status->init();
if (entry.next())
oldClose();
if (!(status->getState() & IStatus::STATE_ERRORS))
y->destroy(Y::DF_RELEASE);
}
}
} // namespace Why } // namespace Why
struct TEB struct TEB
@ -3892,14 +3915,11 @@ void YEvents::cancel(CheckStatusWrapper* status)
{ {
YEntry<YEvents> entry(status, this, CHECK_WARN_ZERO_HANDLE); YEntry<YEvents> entry(status, this, CHECK_WARN_ZERO_HANDLE);
if (entry.next()) done(status, entry, this, [&]{
entry.next()->cancel(status); entry.next()->cancel(status);
if (status->getErrors()[1] == isc_att_shutdown)
if (status->getErrors()[1] == isc_att_shutdown) status->init();
status->init(); }, [&]{entry.next()->cancel_1(status);});
if (!(status->getState() & IStatus::STATE_ERRORS))
destroy(DF_RELEASE);
} }
catch (const Exception& e) catch (const Exception& e)
{ {
@ -3907,6 +3927,11 @@ void YEvents::cancel(CheckStatusWrapper* status)
} }
} }
void YEvents::cancel_1(CheckStatusWrapper* status)
{
cancel(status);
}
//------------------------------------- //-------------------------------------
@ -4037,11 +4062,7 @@ void YRequest::free(CheckStatusWrapper* status)
{ {
YEntry<YRequest> entry(status, this, CHECK_WARN_ZERO_HANDLE); YEntry<YRequest> entry(status, this, CHECK_WARN_ZERO_HANDLE);
if (entry.next()) done(status, entry, this, [&]{entry.next()->free(status);}, [&]{entry.next()->free_1(status);});
entry.next()->free(status);
if (!(status->getState() & IStatus::STATE_ERRORS))
destroy(DF_RELEASE);
} }
catch (const Exception& e) catch (const Exception& e)
{ {
@ -4049,6 +4070,11 @@ void YRequest::free(CheckStatusWrapper* status)
} }
} }
void YRequest::free_1(CheckStatusWrapper* status)
{
free(status);
}
//------------------------------------- //-------------------------------------
@ -4132,11 +4158,7 @@ void YBlob::cancel(CheckStatusWrapper* status)
{ {
YEntry<YBlob> entry(status, this, CHECK_WARN_ZERO_HANDLE); YEntry<YBlob> entry(status, this, CHECK_WARN_ZERO_HANDLE);
if (entry.next()) done(status, entry, this, [&]{entry.next()->cancel(status);}, [&]{entry.next()->cancel_1(status);});
entry.next()->cancel(status);
if (!(status->getState() & IStatus::STATE_ERRORS))
destroy(DF_RELEASE);
} }
catch (const Exception& e) catch (const Exception& e)
{ {
@ -4144,17 +4166,18 @@ void YBlob::cancel(CheckStatusWrapper* status)
} }
} }
void YBlob::cancel_1(CheckStatusWrapper* status)
{
cancel(status);
}
void YBlob::close(CheckStatusWrapper* status) void YBlob::close(CheckStatusWrapper* status)
{ {
try try
{ {
YEntry<YBlob> entry(status, this, CHECK_WARN_ZERO_HANDLE); YEntry<YBlob> entry(status, this, CHECK_WARN_ZERO_HANDLE);
if (entry.next()) done(status, entry, this, [&]{entry.next()->close(status);}, [&]{entry.next()->close_1(status);});
entry.next()->close(status);
if (!(status->getState() & IStatus::STATE_ERRORS))
destroy(DF_RELEASE);
} }
catch (const Exception& e) catch (const Exception& e)
{ {
@ -4162,6 +4185,11 @@ void YBlob::close(CheckStatusWrapper* status)
} }
} }
void YBlob::close_1(CheckStatusWrapper* status)
{
close(status);
}
int YBlob::seek(CheckStatusWrapper* status, int mode, int offset) int YBlob::seek(CheckStatusWrapper* status, int mode, int offset)
{ {
try try
@ -4429,11 +4457,7 @@ void YStatement::free(CheckStatusWrapper* status)
{ {
YEntry<YStatement> entry(status, this, CHECK_WARN_ZERO_HANDLE); YEntry<YStatement> entry(status, this, CHECK_WARN_ZERO_HANDLE);
if (entry.next()) done(status, entry, this, [&]{entry.next()->free(status);}, [&]{entry.next()->free_1(status);});
entry.next()->free(status);
if (!(status->getState() & IStatus::STATE_ERRORS))
destroy(DF_RELEASE);
} }
catch (const Exception& e) catch (const Exception& e)
{ {
@ -4441,6 +4465,12 @@ void YStatement::free(CheckStatusWrapper* status)
} }
} }
void YStatement::free_1(CheckStatusWrapper* status)
{
free(status);
}
YBatch* YStatement::createBatch(CheckStatusWrapper* status, IMessageMetadata* inMetadata, unsigned parLength, YBatch* YStatement::createBatch(CheckStatusWrapper* status, IMessageMetadata* inMetadata, unsigned parLength,
const unsigned char* par) const unsigned char* par)
{ {
@ -4838,17 +4868,14 @@ IMessageMetadata* YResultSet::getMetadata(CheckStatusWrapper* status)
return NULL; return NULL;
} }
void YResultSet::close(CheckStatusWrapper* status) void YResultSet::close(CheckStatusWrapper* status)
{ {
try try
{ {
YEntry<YResultSet> entry(status, this, CHECK_WARN_ZERO_HANDLE); YEntry<YResultSet> entry(status, this, CHECK_WARN_ZERO_HANDLE);
if (entry.next()) done(status, entry, this, [&]{entry.next()->close(status);}, [&]{entry.next()->close_1(status);});
entry.next()->close(status);
if (!(status->getState() & IStatus::STATE_ERRORS))
destroy(DF_RELEASE);
} }
catch (const Exception& e) catch (const Exception& e)
{ {
@ -4856,6 +4883,12 @@ void YResultSet::close(CheckStatusWrapper* status)
} }
} }
void YResultSet::close_1(CheckStatusWrapper* status)
{
close(status);
}
//------------------------------------- //-------------------------------------
@ -5034,11 +5067,7 @@ void YBatch::close(CheckStatusWrapper* status)
{ {
YEntry<YBatch> entry(status, this, CHECK_WARN_ZERO_HANDLE); YEntry<YBatch> entry(status, this, CHECK_WARN_ZERO_HANDLE);
if (entry.next()) done(status, entry, this, [&]{entry.next()->close(status);}, [&]{entry.next()->close_1(status);});
entry.next()->close(status);
if (!(status->getState() & IStatus::STATE_ERRORS))
destroy(DF_RELEASE);
} }
catch (const Exception& e) catch (const Exception& e)
{ {
@ -5047,6 +5076,12 @@ void YBatch::close(CheckStatusWrapper* status)
} }
void YBatch::close_1(CheckStatusWrapper* status)
{
close(status);
}
//------------------------------------- //-------------------------------------
@ -5082,11 +5117,7 @@ void YReplicator::close(CheckStatusWrapper* status)
{ {
YEntry<YReplicator> entry(status, this, CHECK_WARN_ZERO_HANDLE); YEntry<YReplicator> entry(status, this, CHECK_WARN_ZERO_HANDLE);
if (entry.next()) done(status, entry, this, [&]{entry.next()->close(status);}, [&]{entry.next()->close_1(status);});
entry.next()->close(status);
if (!(status->getState() & IStatus::STATE_ERRORS))
destroy(DF_RELEASE);
} }
catch (const Exception& e) catch (const Exception& e)
{ {
@ -5095,6 +5126,12 @@ void YReplicator::close(CheckStatusWrapper* status)
} }
void YReplicator::close_1(CheckStatusWrapper* status)
{
close(status);
}
//------------------------------------- //-------------------------------------
@ -5133,8 +5170,8 @@ void YTransaction::destroy(unsigned dstrFlags)
// can't release cursors by itself. See also CORE-6067. // can't release cursors by itself. See also CORE-6067.
const bool releaseCursors = handle; const bool releaseCursors = handle;
childBlobs.destroy(dstrFlags & ~DF_RELEASE); childBlobs.destroy(dstrFlags & ~(DF_RELEASE | DF_KEEP_NEXT));
childCursors.destroy(releaseCursors ? dstrFlags : dstrFlags & ~DF_RELEASE); childCursors.destroy((releaseCursors ? dstrFlags : dstrFlags & ~DF_RELEASE) & ~DF_KEEP_NEXT);
YAttachment* att = attachment.release(); YAttachment* att = attachment.release();
if (att) if (att)
@ -5186,10 +5223,7 @@ void YTransaction::commit(CheckStatusWrapper* status)
{ {
YEntry<YTransaction> entry(status, this); YEntry<YTransaction> entry(status, this);
entry.next()->commit(status); done(status, entry, this, [&]{entry.next()->commit(status);}, [&]{entry.next()->commit_1(status);});
if (!(status->getState() & IStatus::STATE_ERRORS))
destroy(DF_RELEASE);
} }
catch (const Exception& e) catch (const Exception& e)
{ {
@ -5217,13 +5251,11 @@ void YTransaction::rollback(CheckStatusWrapper* status)
{ {
YEntry<YTransaction> entry(status, this, CHECK_WARN_ZERO_HANDLE); YEntry<YTransaction> entry(status, this, CHECK_WARN_ZERO_HANDLE);
if (entry.next()) done(status, entry, this, [&]{
entry.next()->rollback(status); entry.next()->rollback(status);
if (isNetworkError(status)) if (isNetworkError(status))
status->init(); status->init();
}, [&]{entry.next()->rollback_1(status);});
if (!(status->getState() & IStatus::STATE_ERRORS))
destroy(DF_RELEASE);
} }
catch (const Exception& e) catch (const Exception& e)
{ {
@ -5274,6 +5306,22 @@ void YTransaction::disconnect(CheckStatusWrapper* status)
} }
} }
void YTransaction::commit_1(CheckStatusWrapper* status)
{
commit(status);
}
void YTransaction::rollback_1(CheckStatusWrapper* status)
{
rollback(status);
}
void YTransaction::disconnect_1(CheckStatusWrapper* status)
{
disconnect(status);
}
void YTransaction::addCleanupHandler(CheckStatusWrapper* status, CleanupCallback* callback) void YTransaction::addCleanupHandler(CheckStatusWrapper* status, CleanupCallback* callback)
{ {
try try
@ -5403,12 +5451,13 @@ void YAttachment::destroy(unsigned dstrFlags)
cleanupHandlers.clear(); cleanupHandlers.clear();
childRequests.destroy(dstrFlags & ~DF_RELEASE); unsigned childFlags = dstrFlags & ~(DF_KEEP_NEXT | DF_RELEASE);
childStatements.destroy(dstrFlags & ~DF_RELEASE); childRequests.destroy(childFlags);
childIscStatements.destroy(dstrFlags & ~DF_RELEASE); childStatements.destroy(childFlags);
childBlobs.destroy(dstrFlags & ~DF_RELEASE); childIscStatements.destroy(childFlags);
childEvents.destroy(dstrFlags & ~DF_RELEASE); childBlobs.destroy(childFlags);
childTransactions.destroy(dstrFlags & ~DF_RELEASE); childEvents.destroy(childFlags);
childTransactions.destroy(childFlags);
removeHandle(&attachments, handle); removeHandle(&attachments, handle);
@ -5863,14 +5912,11 @@ void YAttachment::detach(CheckStatusWrapper* status)
{ {
YEntry<YAttachment> entry(status, this, CHECK_NONE); YEntry<YAttachment> entry(status, this, CHECK_NONE);
if (entry.next()) done(status, entry, this, [&]{
entry.next()->detach(status); entry.next()->detach(status);
if (isNetworkError(status))
if (isNetworkError(status)) status->init();
status->init(); }, [&]{entry.next()->detach_1(status);});
if (!(status->getState() & IStatus::STATE_ERRORS))
destroy(DF_RELEASE);
} }
catch (const Exception& e) catch (const Exception& e)
{ {
@ -5878,16 +5924,18 @@ void YAttachment::detach(CheckStatusWrapper* status)
} }
} }
void YAttachment::detach_1(CheckStatusWrapper* status)
{
detach(status);
}
void YAttachment::dropDatabase(CheckStatusWrapper* status) void YAttachment::dropDatabase(CheckStatusWrapper* status)
{ {
try try
{ {
YEntry<YAttachment> entry(status, this); YEntry<YAttachment> entry(status, this);
entry.next()->dropDatabase(status); done(status, entry, this, [&]{entry.next()->dropDatabase(status);}, [&]{entry.next()->dropDatabase_1(status);});
if (!(status->getState() & IStatus::STATE_ERRORS))
destroy(DF_RELEASE);
} }
catch (const Exception& e) catch (const Exception& e)
{ {
@ -5895,6 +5943,11 @@ void YAttachment::dropDatabase(CheckStatusWrapper* status)
} }
} }
void YAttachment::dropDatabase_1(CheckStatusWrapper* status)
{
dropDatabase(status);
}
void YAttachment::addCleanupHandler(CheckStatusWrapper* status, CleanupCallback* callback) void YAttachment::addCleanupHandler(CheckStatusWrapper* status, CleanupCallback* callback)
{ {
try try
@ -6101,10 +6154,7 @@ void YService::detach(CheckStatusWrapper* status)
{ {
YEntry<YService> entry(status, this, CHECK_WARN_ZERO_HANDLE); YEntry<YService> entry(status, this, CHECK_WARN_ZERO_HANDLE);
if (entry.next()) done(status, entry, this, [&]{entry.next()->detach(status);}, [&]{entry.next()->detach_1(status);});
entry.next()->detach(status);
destroy(DF_RELEASE);
} }
catch (const Exception& e) catch (const Exception& e)
{ {
@ -6112,6 +6162,11 @@ void YService::detach(CheckStatusWrapper* status)
} }
} }
void YService::detach_1(CheckStatusWrapper* status)
{
detach(status);
}
void YService::query(CheckStatusWrapper* status, unsigned int sendLength, const unsigned char* sendItems, void YService::query(CheckStatusWrapper* status, unsigned int sendLength, const unsigned char* sendItems,
unsigned int receiveLength, const unsigned char* receiveItems, unsigned int receiveLength, const unsigned char* receiveItems,
unsigned int bufferLength, unsigned char* buffer) unsigned int bufferLength, unsigned char* buffer)