From: <ale...@us...> - 2014-12-18 16:54:53
|
Revision: 60389 http://sourceforge.net/p/firebird/code/60389 Author: alexpeshkoff Date: 2014-12-18 16:54:44 +0000 (Thu, 18 Dec 2014) Log Message: ----------- Changed struct DtcStart to interface. Make external programs build again with minimum changes. Modified Paths: -------------- firebird/trunk/examples/interfaces/01.create.cpp firebird/trunk/examples/interfaces/02.update.cpp firebird/trunk/examples/interfaces/03.select.cpp firebird/trunk/examples/interfaces/04.print_table.cpp firebird/trunk/src/include/firebird/FirebirdInterface.idl firebird/trunk/src/include/firebird/IdlFbInterfaces.h firebird/trunk/src/include/firebird/Interface.h firebird/trunk/src/include/firebird/Message.h firebird/trunk/src/include/firebird/UdrEngine.h firebird/trunk/src/yvalve/DistributedTransaction.cpp firebird/trunk/src/yvalve/MasterImplementation.h firebird/trunk/src/yvalve/PluginManager.cpp firebird/trunk/src/yvalve/why.cpp Added Paths: ----------- firebird/trunk/examples/interfaces/ifaceExamples.h Modified: firebird/trunk/examples/interfaces/01.create.cpp =================================================================== --- firebird/trunk/examples/interfaces/01.create.cpp 2014-12-18 16:23:03 UTC (rev 60388) +++ firebird/trunk/examples/interfaces/01.create.cpp 2014-12-18 16:54:44 UTC (rev 60389) @@ -33,26 +33,12 @@ * Contributor(s): ______________________________________. */ -#include <stdlib.h> -#include <stdio.h> -#include <string.h> +#include "ifaceExamples.h" -#include <ibase.h> -#include <firebird/Interface.h> - -using namespace Firebird; - // Here we get access to master interface. This is main interface of firebird, // and the only one for getting which there is special function in our API. static IMaster* master = fb_get_master_interface(); -// Probably not best way of error processing, but it's OK for a sample -static void check(IStatus* s, const char* text) -{ - if (s->getStatus() & IStatus::FB_HAS_ERRORS) - throw text; -} - int main() { int rc = 0; Modified: firebird/trunk/examples/interfaces/02.update.cpp =================================================================== --- firebird/trunk/examples/interfaces/02.update.cpp 2014-12-18 16:23:03 UTC (rev 60388) +++ firebird/trunk/examples/interfaces/02.update.cpp 2014-12-18 16:54:44 UTC (rev 60389) @@ -35,15 +35,8 @@ * Alex Peshkov, 2013 */ -#include <stdlib.h> -#include <stdio.h> -#include <string.h> +#include "ifaceExamples.h" -#include <ibase.h> -#include <firebird/Interface.h> - -using namespace Firebird; - static IMaster* master = fb_get_master_interface(); int get_input(char*, double*); @@ -53,12 +46,6 @@ {0.05, 1.00, 0.075, 0.10, 0}; int Input_ptr = 0; -static void check(IStatus* s, const char* text) -{ - if (s->getStatus() & IStatus::FB_HAS_ERRORS) - throw text; -} - int main() { int rc = 0; Modified: firebird/trunk/examples/interfaces/03.select.cpp =================================================================== --- firebird/trunk/examples/interfaces/03.select.cpp 2014-12-18 16:23:03 UTC (rev 60388) +++ firebird/trunk/examples/interfaces/03.select.cpp 2014-12-18 16:54:44 UTC (rev 60389) @@ -33,23 +33,10 @@ * Contributor(s): ______________________________________. */ -#include <stdlib.h> -#include <stdio.h> -#include <string.h> +#include "ifaceExamples.h" -#include <ibase.h> -#include <firebird/Interface.h> - -using namespace Firebird; - static IMaster* master = fb_get_master_interface(); -static void check(IStatus* s, const char* text) -{ - if (s->getStatus() & IStatus::FB_HAS_ERRORS) - throw text; -} - int main() { int rc = 0; Modified: firebird/trunk/examples/interfaces/04.print_table.cpp =================================================================== --- firebird/trunk/examples/interfaces/04.print_table.cpp 2014-12-18 16:23:03 UTC (rev 60388) +++ firebird/trunk/examples/interfaces/04.print_table.cpp 2014-12-18 16:54:44 UTC (rev 60389) @@ -32,23 +32,11 @@ * All Rights Reserved. * Contributor(s): ______________________________________. */ -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <ibase.h> -#include <firebird/Interface.h> +#include "ifaceExamples.h" -using namespace Firebird; - static IMaster* master = fb_get_master_interface(); -static void check(IStatus* s, const char* text) -{ - if (s->getStatus() & IStatus::FB_HAS_ERRORS) - throw text; -} - struct MyField { const char* name; Added: firebird/trunk/examples/interfaces/ifaceExamples.h =================================================================== --- firebird/trunk/examples/interfaces/ifaceExamples.h (rev 0) +++ firebird/trunk/examples/interfaces/ifaceExamples.h 2014-12-18 16:54:44 UTC (rev 60389) @@ -0,0 +1,60 @@ +/* + * PROGRAM: Object oriented API samples. + * MODULE: ifaceExamples.h + * DESCRIPTION: A number of common defines for all samples. + * + * The contents of this file are subject to the Initial + * Developer's Public License Version 1.0 (the "License"); + * you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * http://www.ibphoenix.com/main.nfs?a=ibphoenix&page=ibp_idpl. + * + * Software distributed under the License is distributed AS IS, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. + * See the License for the specific language governing rights + * and limitations under the License. + * + * The Original Code was created by Alexander Peshkoff + * for the Firebird Open Source RDBMS project. + * + * Copyright (c) 2014 Alexander Peshkoff <pes...@ma...> + * and all contributors signed below. + * + * All Rights Reserved. + * Contributor(s): ______________________________________. + */ + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> + +#include <ibase.h> +#include <firebird/Interface.h> + +using namespace Firebird; + +typedef FirebirdApi<class ExamplesPolicy> Api; +FB_USE_API(Api, I) + +// Dummy policy - to be enhanced +class ExamplesPolicy +{ +public: + template <unsigned V, typename T> + static inline bool checkVersion(T* versioned, IStatus* status) + { return true; } + static void checkException(Api::Status*) { } + static void catchException(Api::Status*) { } + typedef Api::Status* Status; +}; + + +// Declare function to get access to master interface. +DECLARE_GET_MASTER(ExamplesPolicy); + +// Probably not best way of error processing, but it's OK for a sample +static void check(IStatus* s, const char* text) +{ + if (s->getStatus() & IStatus::FB_HAS_ERRORS) + throw text; +} Property changes on: firebird/trunk/examples/interfaces/ifaceExamples.h ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +text/x-chdr \ No newline at end of property Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Modified: firebird/trunk/src/include/firebird/FirebirdInterface.idl =================================================================== --- firebird/trunk/src/include/firebird/FirebirdInterface.idl 2014-12-18 16:23:03 UTC (rev 60388) +++ firebird/trunk/src/include/firebird/FirebirdInterface.idl 2014-12-18 16:54:44 UTC (rev 60389) @@ -533,21 +533,22 @@ void setDbCryptCallback(Status status, CryptKeyCallback cryptCallback); } -/*** FIXME: -// DtcStart - structure to start transaction over >1 attachments (former TEB) -struct DtcStart +// Helper to start transaction over >1 attachments (former TEB) +interface DtcStart : Disposable { - Attachment attachment; - const uchar* tpb; - uint tpbLength; + void setComponent(Status status, Attachment att); + void setWithParam(Status status, Attachment att, uint length, const uchar* tpb); + uint getCount(Status status); + Attachment getAttachment(Status status, uint pos); + const uchar* getTpb(Status status, uint pos, uint* length); } -***/ // Distributed transactions coordinator interface Dtc : Versioned { - Transaction start(Status status, uint cnt, DtcStart* components); + Transaction start(Status status, DtcStart components); Transaction join(Status status, Transaction one, Transaction two); + DtcStart startBuilder(Status status); } Modified: firebird/trunk/src/include/firebird/IdlFbInterfaces.h =================================================================== --- firebird/trunk/src/include/firebird/IdlFbInterfaces.h 2014-12-18 16:23:03 UTC (rev 60388) +++ firebird/trunk/src/include/firebird/IdlFbInterfaces.h 2014-12-18 16:54:44 UTC (rev 60389) @@ -56,6 +56,7 @@ class Attachment; class Service; class Provider; + class DtcStart; class Dtc; class Auth; class Writer; @@ -2009,13 +2010,78 @@ } }; + class DtcStart : public Disposable + { + public: + struct VTable : public Disposable::VTable + { + void (CLOOP_CARG *setComponent)(DtcStart* self, Status* status, Attachment* att) throw(); + void (CLOOP_CARG *setWithParam)(DtcStart* self, Status* status, Attachment* att, unsigned length, const unsigned char* tpb) throw(); + unsigned (CLOOP_CARG *getCount)(DtcStart* self, Status* status) throw(); + Attachment* (CLOOP_CARG *getAttachment)(DtcStart* self, Status* status, unsigned pos) throw(); + const unsigned char* (CLOOP_CARG *getTpb)(DtcStart* self, Status* status, unsigned pos, unsigned* length) throw(); + }; + + protected: + DtcStart(DoNotInherit) + : Disposable(DoNotInherit()) + { + } + + ~DtcStart() + { + } + + public: + static const unsigned VERSION = 3; + + void setComponent(Status* status, Attachment* att) + { + typename Policy::Status status2(status); + static_cast<VTable*>(this->cloopVTable)->setComponent(this, status2, att); + Policy::checkException(status2); + } + + void setWithParam(Status* status, Attachment* att, unsigned length, const unsigned char* tpb) + { + typename Policy::Status status2(status); + static_cast<VTable*>(this->cloopVTable)->setWithParam(this, status2, att, length, tpb); + Policy::checkException(status2); + } + + unsigned getCount(Status* status) + { + typename Policy::Status status2(status); + unsigned ret = static_cast<VTable*>(this->cloopVTable)->getCount(this, status2); + Policy::checkException(status2); + return ret; + } + + Attachment* getAttachment(Status* status, unsigned pos) + { + typename Policy::Status status2(status); + Attachment* ret = static_cast<VTable*>(this->cloopVTable)->getAttachment(this, status2, pos); + Policy::checkException(status2); + return ret; + } + + const unsigned char* getTpb(Status* status, unsigned pos, unsigned* length) + { + typename Policy::Status status2(status); + const unsigned char* ret = static_cast<VTable*>(this->cloopVTable)->getTpb(this, status2, pos, length); + Policy::checkException(status2); + return ret; + } + }; + class Dtc : public Versioned { public: struct VTable : public Versioned::VTable { - Transaction* (CLOOP_CARG *start)(Dtc* self, Status* status, unsigned cnt, DtcStart* components) throw(); + Transaction* (CLOOP_CARG *start)(Dtc* self, Status* status, DtcStart* components) throw(); Transaction* (CLOOP_CARG *join)(Dtc* self, Status* status, Transaction* one, Transaction* two) throw(); + DtcStart* (CLOOP_CARG *startBuilder)(Dtc* self, Status* status) throw(); }; protected: @@ -2031,10 +2097,10 @@ public: static const unsigned VERSION = 2; - Transaction* start(Status* status, unsigned cnt, DtcStart* components) + Transaction* start(Status* status, DtcStart* components) { typename Policy::Status status2(status); - Transaction* ret = static_cast<VTable*>(this->cloopVTable)->start(this, status2, cnt, components); + Transaction* ret = static_cast<VTable*>(this->cloopVTable)->start(this, status2, components); Policy::checkException(status2); return ret; } @@ -2046,6 +2112,14 @@ Policy::checkException(status2); return ret; } + + DtcStart* startBuilder(Status* status) + { + typename Policy::Status status2(status); + DtcStart* ret = static_cast<VTable*>(this->cloopVTable)->startBuilder(this, status2); + Policy::checkException(status2); + return ret; + } }; class Auth : public PluginBase @@ -8636,6 +8710,141 @@ }; template <typename Name, typename Base> + class DtcStartBaseImpl : public Base + { + public: + typedef DtcStart Declaration; + + DtcStartBaseImpl(DoNotInherit = DoNotInherit()) + { + static struct VTableImpl : Base::VTable + { + VTableImpl() + { + this->version = Base::VERSION; + this->getModule = &Name::cloopgetModuleDispatcher; + this->dispose = &Name::cloopdisposeDispatcher; + this->setComponent = &Name::cloopsetComponentDispatcher; + this->setWithParam = &Name::cloopsetWithParamDispatcher; + this->getCount = &Name::cloopgetCountDispatcher; + this->getAttachment = &Name::cloopgetAttachmentDispatcher; + this->getTpb = &Name::cloopgetTpbDispatcher; + } + } vTable; + + this->cloopVTable = &vTable; + } + + static void CLOOP_CARG cloopsetComponentDispatcher(DtcStart* self, Status* status, Attachment* att) throw() + { + try + { + static_cast<Name*>(self)->Name::setComponent(status, att); + } + catch (...) + { + Policy::catchException(status); + } + } + + static void CLOOP_CARG cloopsetWithParamDispatcher(DtcStart* self, Status* status, Attachment* att, unsigned length, const unsigned char* tpb) throw() + { + try + { + static_cast<Name*>(self)->Name::setWithParam(status, att, length, tpb); + } + catch (...) + { + Policy::catchException(status); + } + } + + static unsigned CLOOP_CARG cloopgetCountDispatcher(DtcStart* self, Status* status) throw() + { + try + { + return static_cast<Name*>(self)->Name::getCount(status); + } + catch (...) + { + Policy::catchException(status); + return static_cast<unsigned>(0); + } + } + + static Attachment* CLOOP_CARG cloopgetAttachmentDispatcher(DtcStart* self, Status* status, unsigned pos) throw() + { + try + { + return static_cast<Name*>(self)->Name::getAttachment(status, pos); + } + catch (...) + { + Policy::catchException(status); + return static_cast<Attachment*>(0); + } + } + + static const unsigned char* CLOOP_CARG cloopgetTpbDispatcher(DtcStart* self, Status* status, unsigned pos, unsigned* length) throw() + { + try + { + return static_cast<Name*>(self)->Name::getTpb(status, pos, length); + } + catch (...) + { + Policy::catchException(status); + return static_cast<const unsigned char*>(0); + } + } + + static void CLOOP_CARG cloopdisposeDispatcher(Disposable* self) throw() + { + try + { + static_cast<Name*>(self)->Name::dispose(); + } + catch (...) + { + Policy::catchException(0); + } + } + + static PluginModule* CLOOP_CARG cloopgetModuleDispatcher(Versioned* self) throw() + { + try + { + return static_cast<Name*>(self)->Name::getModule(); + } + catch (...) + { + Policy::catchException(0); + return static_cast<PluginModule*>(0); + } + } + }; + + template <typename Name, typename Base = DisposableImpl<Name, Inherit<VersionedImpl<Name, Inherit<DtcStart> > > > > + class DtcStartImpl : public DtcStartBaseImpl<Name, Base> + { + protected: + DtcStartImpl(DoNotInherit = DoNotInherit()) + { + } + + public: + virtual ~DtcStartImpl() + { + } + + virtual void setComponent(Status* status, Attachment* att) = 0; + virtual void setWithParam(Status* status, Attachment* att, unsigned length, const unsigned char* tpb) = 0; + virtual unsigned getCount(Status* status) = 0; + virtual Attachment* getAttachment(Status* status, unsigned pos) = 0; + virtual const unsigned char* getTpb(Status* status, unsigned pos, unsigned* length) = 0; + }; + + template <typename Name, typename Base> class DtcBaseImpl : public Base { public: @@ -8651,17 +8860,18 @@ this->getModule = &Name::cloopgetModuleDispatcher; this->start = &Name::cloopstartDispatcher; this->join = &Name::cloopjoinDispatcher; + this->startBuilder = &Name::cloopstartBuilderDispatcher; } } vTable; this->cloopVTable = &vTable; } - static Transaction* CLOOP_CARG cloopstartDispatcher(Dtc* self, Status* status, unsigned cnt, DtcStart* components) throw() + static Transaction* CLOOP_CARG cloopstartDispatcher(Dtc* self, Status* status, DtcStart* components) throw() { try { - return static_cast<Name*>(self)->Name::start(status, cnt, components); + return static_cast<Name*>(self)->Name::start(status, components); } catch (...) { @@ -8683,6 +8893,19 @@ } } + static DtcStart* CLOOP_CARG cloopstartBuilderDispatcher(Dtc* self, Status* status) throw() + { + try + { + return static_cast<Name*>(self)->Name::startBuilder(status); + } + catch (...) + { + Policy::catchException(status); + return static_cast<DtcStart*>(0); + } + } + static PluginModule* CLOOP_CARG cloopgetModuleDispatcher(Versioned* self) throw() { try @@ -8710,8 +8933,9 @@ { } - virtual Transaction* start(Status* status, unsigned cnt, DtcStart* components) = 0; + virtual Transaction* start(Status* status, DtcStart* components) = 0; virtual Transaction* join(Status* status, Transaction* one, Transaction* two) = 0; + virtual DtcStart* startBuilder(Status* status) = 0; }; template <typename Name, typename Base> Modified: firebird/trunk/src/include/firebird/Interface.h =================================================================== --- firebird/trunk/src/include/firebird/Interface.h 2014-12-18 16:23:03 UTC (rev 60388) +++ firebird/trunk/src/include/firebird/Interface.h 2014-12-18 16:54:44 UTC (rev 60389) @@ -42,12 +42,10 @@ { struct FbCryptKey; -struct DtcStart; #include "IdlFbInterfaces.h" #define FB_USE_API(name, prefix) \ - /* awk <FirebirdInterface.idl '($1 == "interface") {printf "\t\ttypedef name::%s prefix##%s;\n", $2, $2;}' */ \ typedef name::Versioned prefix##Versioned; \ typedef name::ReferenceCounted prefix##ReferenceCounted; \ typedef name::Disposable prefix##Disposable; \ @@ -75,6 +73,7 @@ typedef name::Attachment prefix##Attachment; \ typedef name::Service prefix##Service; \ typedef name::Provider prefix##Provider; \ + typedef name::DtcStart prefix##DtcStart; \ typedef name::Dtc prefix##Dtc; \ typedef name::Auth prefix##Auth; \ typedef name::Writer prefix##Writer; \ @@ -174,15 +173,6 @@ unsigned decryptLength; // Ignored when decryptKey is NULL }; -struct DtcStart -{ - IAttachment* attachment; - const unsigned char* tpb; - unsigned tpbLength; -}; - -typedef void PluginEntrypoint(IMaster* masterInterface); - #ifdef INCLUDE_Firebird_H // Building internal module // This item is for ISC API emulation only @@ -196,12 +186,13 @@ #define FB_PLUGIN_ENTRY_POINT firebird_plugin -extern "C" -{ - // Additional API function. - // Should be used only in non-plugin modules. - // All plugins including providers should use passed at init time interface instead. - Firebird::IMaster* ISC_EXPORT fb_get_master_interface(); -} +// Additional API function. +// Should be used only in non-plugin modules. +// All plugins including providers should use passed at init time interface instead. +#define DECLARE_GET_MASTER(P) extern "C" Firebird::FirebirdApi<P>::Master* ISC_EXPORT fb_get_master_interface(); +#ifdef INCLUDE_Firebird_H // Building internal module +DECLARE_GET_MASTER(Firebird::FirebirdPolicy) +#endif //INCLUDE_Firebird_H + #endif // FB_INCLUDE_INTERFACE Modified: firebird/trunk/src/include/firebird/Message.h =================================================================== --- firebird/trunk/src/include/firebird/Message.h 2014-12-18 16:23:03 UTC (rev 60388) +++ firebird/trunk/src/include/firebird/Message.h 2014-12-18 16:54:44 UTC (rev 60389) @@ -30,6 +30,33 @@ #include <time.h> #include <string.h> +//---------------------------------------------------------------- +// This ifdef is a dirty hack to make tests (fbstuff) to compile +#ifndef INCLUDE_Firebird_H + +namespace Firebird +{ +typedef FirebirdApi<class TempPolicy> Api; +FB_USE_API(Api, I) + +class TempPolicy +{ +public: + template <unsigned V, typename T> + static inline bool checkVersion(T* versioned, IStatus* status) + { return true; } + static void checkException(Api::Status*) { } + static void catchException(Api::Status*) { } + typedef Api::Status* Status; +}; +} //namespace Firebird + +DECLARE_GET_MASTER(Firebird::TempPolicy) +#define INCLUDE_Firebird_H + +#endif +//- END OF HACK -------------------------------------------------- + #define FB_MESSAGE(name, fields) \ FB__MESSAGE_I(name, 2, FB_BOOST_PP_CAT(FB__MESSAGE_X fields, 0), ) Modified: firebird/trunk/src/include/firebird/UdrEngine.h =================================================================== --- firebird/trunk/src/include/firebird/UdrEngine.h 2014-12-18 16:23:03 UTC (rev 60388) +++ firebird/trunk/src/include/firebird/UdrEngine.h 2014-12-18 16:54:44 UTC (rev 60389) @@ -25,6 +25,34 @@ #include "./Interface.h" +//---------------------------------------------------------------- +// This ifdef is a dirty hack to make tests (fbstuff) to compile +#ifndef INCLUDE_Firebird_H + +namespace Firebird +{ +typedef FirebirdApi<class TempPolicy> Api; +FB_USE_API(Api, I) + +class TempPolicy +{ +public: + template <unsigned V, typename T> + static inline bool checkVersion(T* versioned, IStatus* status) + { return true; } + static void checkException(Api::Status*) { } + static void catchException(Api::Status*) { } + typedef Api::Status* Status; +}; +} //namespace Firebird + +DECLARE_GET_MASTER(Firebird::TempPolicy) +#define INCLUDE_Firebird_H + +#endif +//- END OF HACK -------------------------------------------------- + + #ifndef FB_EXPORTED #if defined(DARWIN) #define FB_EXPORTED __attribute__((visibility("default"))) Modified: firebird/trunk/src/yvalve/DistributedTransaction.cpp =================================================================== --- firebird/trunk/src/yvalve/DistributedTransaction.cpp 2014-12-18 16:23:03 UTC (rev 60388) +++ firebird/trunk/src/yvalve/DistributedTransaction.cpp 2014-12-18 16:54:44 UTC (rev 60389) @@ -498,7 +498,7 @@ namespace Why { -YTransaction* Dtc::start(IStatus* status, unsigned int cnt, DtcStart* components) +YTransaction* Dtc::start(IStatus* status, IDtcStart* components) { try { @@ -506,26 +506,37 @@ RefPtr<DTransaction> dtransaction(new DTransaction); - for (unsigned int i = 0; i < cnt; ++i) + unsigned cnt = components->getCount(status); + if (status->getStatus() & Firebird::IStatus::FB_HAS_ERRORS) + status_exception::raise(status); + + for (unsigned i = 0; i < cnt; ++i) { - RefPtr<ITransaction> transaction(components[i].attachment-> - startTransaction(status, components[i].tpbLength, components[i].tpb)); + RefPtr<IAttachment> att(REF_NO_INCR, components->getAttachment(status, i)); + if (status->getStatus() & Firebird::IStatus::FB_HAS_ERRORS) + status_exception::raise(status); + unsigned tpbLen; + const unsigned char* tpb = components->getTpb(status, i, &tpbLen); if (status->getStatus() & Firebird::IStatus::FB_HAS_ERRORS) - return NULL; + status_exception::raise(status); - dtransaction->join(status, transaction); + ITransaction* started = att->startTransaction(status, tpbLen, tpb); + if (status->getStatus() & Firebird::IStatus::FB_HAS_ERRORS) + status_exception::raise(status); + dtransaction->join(status, started); if (status->getStatus() & Firebird::IStatus::FB_HAS_ERRORS) { - LocalStatus tmp; - dtransaction->rollback(&tmp); - return NULL; + started->release(); + status_exception::raise(status); } } + YTransaction* rc = new YTransaction(NULL, dtransaction); dtransaction->addRef(); - return new YTransaction(NULL, dtransaction); + components->dispose(); + return rc; } catch (const Exception& ex) { @@ -564,4 +575,114 @@ return NULL; } +class DtcStart : public DisposeIface<Api::DtcStartImpl<DtcStart> > +{ +public: + DtcStart() + : components(getPool()) + { } + + // IDtcStart implementation + void setComponent(IStatus* status, IAttachment* att) + { + this->setWithParam(status, att, 0, NULL); + } + + void setWithParam(IStatus* status, IAttachment* att, unsigned length, const unsigned char* tpb) + { + try + { + Component toAdd; + toAdd.att = att; + toAdd.tpbLen = length; + toAdd.tpb = tpb; + + components.add(toAdd); + att->addRef(); + } + catch (const Exception& ex) + { + ex.stuffException(status); + } + } + + unsigned getCount(IStatus*) + { + return components.getCount(); + } + + IAttachment* getAttachment(IStatus* status, unsigned pos) + { + try + { + errorOver(pos); + + components[pos].att->addRef(); + return components[pos].att; + } + catch (const Exception& ex) + { + ex.stuffException(status); + } + return NULL; + } + + const unsigned char* getTpb(IStatus* status, unsigned pos, unsigned* length) + { + try + { + errorOver(pos); + + *length = components[pos].tpbLen; + return components[pos].tpb; + } + catch (const Exception& ex) + { + ex.stuffException(status); + } + return NULL; + } + + void dispose() + { + for (unsigned i = 0; i < components.getCount(); ++i) + components[i].att->release(); + + delete this; + } + +private: + struct Component + { + IAttachment* att; + unsigned tpbLen; + const unsigned char* tpb; + }; + + HalfStaticArray<Component, 16> components; + + void errorOver(unsigned n) + { + // TODO: add component num & limit to the message + if (n >= components.getCount()) + (Arg::Gds(isc_random) << "Access to invalid component number in DtcStart").raise(); + } +}; + +IDtcStart* Dtc::startBuilder(IStatus* status) +{ + try + { + status->init(); + + return new DtcStart; + } + catch (const Exception& ex) + { + ex.stuffException(status); + } + + return NULL; +} + } // namespace Why Modified: firebird/trunk/src/yvalve/MasterImplementation.h =================================================================== --- firebird/trunk/src/yvalve/MasterImplementation.h 2014-12-18 16:23:03 UTC (rev 60388) +++ firebird/trunk/src/yvalve/MasterImplementation.h 2014-12-18 16:54:44 UTC (rev 60389) @@ -45,10 +45,10 @@ { public: // IDtc implementation - YTransaction* start(Firebird::IStatus* status, - unsigned int cnt, Firebird::DtcStart* components); + YTransaction* start(Firebird::IStatus* status, Firebird::IDtcStart* components); YTransaction* join(Firebird::IStatus* status, Firebird::ITransaction* one, Firebird::ITransaction* two); + Firebird::IDtcStart* startBuilder(Firebird::IStatus* status); }; class MasterImplementation : public Firebird::AutoIface<Firebird::Api::MasterImpl<MasterImplementation> > Modified: firebird/trunk/src/yvalve/PluginManager.cpp =================================================================== --- firebird/trunk/src/yvalve/PluginManager.cpp 2014-12-18 16:23:03 UTC (rev 60388) +++ firebird/trunk/src/yvalve/PluginManager.cpp 2014-12-18 16:54:44 UTC (rev 60389) @@ -946,6 +946,7 @@ } RefPtr<PluginModule> rc(new PluginModule(module, info.curModule)); + typedef void PluginEntrypoint(IMaster* masterInterface); PluginEntrypoint* startModule; if (module->findSymbol(STRINGIZE(FB_PLUGIN_ENTRY_POINT), startModule)) { Modified: firebird/trunk/src/yvalve/why.cpp =================================================================== --- firebird/trunk/src/yvalve/why.cpp 2014-12-18 16:23:03 UTC (rev 60388) +++ firebird/trunk/src/yvalve/why.cpp 2014-12-18 16:54:44 UTC (rev 60389) @@ -3407,7 +3407,6 @@ StatusVector status(userStatus); TEB* vector = (TEB*) vec; YTransaction* multiTrans = NULL; - DtcStart* ds = NULL; try { @@ -3429,22 +3428,20 @@ return status[1]; } - HalfStaticArray<DtcStart, 16> dtcStartBuffer; - ds = dtcStartBuffer.getBuffer(count); - memset(ds, 0, sizeof(DtcStart) * count); - DtcStart* const end = ds + count; + IDtcStart* ds = MasterImplementation::dtc->startBuilder(&status); + if (status.getStatus() & IStatus::FB_HAS_ERRORS) + return status[1]; - for (DtcStart* p = ds; p < end; ++p, ++vector) + for (unsigned u = 0; u < count; ++u) { RefPtr<YAttachment> attachment(translateHandle(attachments, vector->teb_database)); - p->attachment = attachment; - attachment->addRef(); - p->tpbLength = vector->teb_tpb_length; - p->tpb = reinterpret_cast<const unsigned char*>(vector->teb_tpb); + ds->setWithParam(&status, attachment, vector->teb_tpb_length, + reinterpret_cast<const unsigned char*>(vector->teb_tpb)); + if (status.getStatus() & IStatus::FB_HAS_ERRORS) + return status[1]; } - multiTrans = MasterImplementation::dtc->start(&status, count, ds); - + multiTrans = MasterImplementation::dtc->start(&status, ds); if (multiTrans) *traHandle = multiTrans->getHandle(); } @@ -3458,17 +3455,6 @@ e.stuffException(&status); } - if (ds) - { - DtcStart* const end = ds + count; - - for (DtcStart* p = ds; p < end; ++p) - { - if (p->attachment) - p->attachment->release(); - } - } - return status[1]; } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |