8
0
mirror of https://github.com/FirebirdSQL/firebird.git synced 2025-01-22 20:43:02 +01:00

Add procedure RDB$PROFILER.CANCEL_SESSION.

This commit is contained in:
Adriano dos Santos Fernandes 2022-05-12 09:55:08 -03:00
parent 2f9c1f625f
commit 9365493cde
8 changed files with 113 additions and 0 deletions

View File

@ -154,6 +154,14 @@ Calling `RDB$PROFILER.FINISH_SESSION(TRUE)` has the same semantics of calling `R
Input parameters:
- `FLUSH` type `BOOLEAN NOT NULL`
## Procedure `CANCEL_SESSION`
`RDB$PROFILER.CANCEL_SESSION` cancels the current profiler session.
All session data present in the profiler plugin is discarded and will not be flushed.
Data already flushed is not deleted automatically.
## Procedure `FLUSH`
`RDB$PROFILER.FLUSH` updates the snapshot tables with data from the profile sessions in memory.

View File

@ -220,6 +220,11 @@ namespace Firebird
return ptr;
}
const T* getPtr() const
{
return ptr;
}
protected:
T* assign(T* const p)
{

View File

@ -1719,6 +1719,9 @@ interface ProfilerSession : Disposable
int64 getId();
uint getFlags();
// When closing an attachment, the engine is free to dispose the ProfilerPlugin without call this method in advance.
void cancel(Status status);
void finish(Status status, ISC_TIMESTAMP_TZ timestamp);
//// FIXME: Add memory stats

View File

@ -6696,6 +6696,7 @@ namespace Firebird
{
ISC_INT64 (CLOOP_CARG *getId)(IProfilerSession* self) throw();
unsigned (CLOOP_CARG *getFlags)(IProfilerSession* self) throw();
void (CLOOP_CARG *cancel)(IProfilerSession* self, IStatus* status) throw();
void (CLOOP_CARG *finish)(IProfilerSession* self, IStatus* status, ISC_TIMESTAMP_TZ timestamp) throw();
void (CLOOP_CARG *defineStatement)(IProfilerSession* self, IStatus* status, ISC_INT64 statementId, ISC_INT64 parentStatementId, const char* type, const char* packageName, const char* routineName, const char* sqlText) throw();
void (CLOOP_CARG *defineRecordSource)(IProfilerSession* self, ISC_INT64 statementId, unsigned cursorId, unsigned recSourceId, const char* accessPath, unsigned parentRecSourceId) throw();
@ -6737,6 +6738,13 @@ namespace Firebird
return ret;
}
template <typename StatusType> void cancel(StatusType* status)
{
StatusType::clearException(status);
static_cast<VTable*>(this->cloopVTable)->cancel(this, status);
StatusType::checkException(status);
}
template <typename StatusType> void finish(StatusType* status, ISC_TIMESTAMP_TZ timestamp)
{
StatusType::clearException(status);
@ -20084,6 +20092,7 @@ namespace Firebird
this->dispose = &Name::cloopdisposeDispatcher;
this->getId = &Name::cloopgetIdDispatcher;
this->getFlags = &Name::cloopgetFlagsDispatcher;
this->cancel = &Name::cloopcancelDispatcher;
this->finish = &Name::cloopfinishDispatcher;
this->defineStatement = &Name::cloopdefineStatementDispatcher;
this->defineRecordSource = &Name::cloopdefineRecordSourceDispatcher;
@ -20127,6 +20136,20 @@ namespace Firebird
}
}
static void CLOOP_CARG cloopcancelDispatcher(IProfilerSession* self, IStatus* status) throw()
{
StatusType status2(status);
try
{
static_cast<Name*>(self)->Name::cancel(&status2);
}
catch (...)
{
StatusType::catchException(&status2);
}
}
static void CLOOP_CARG cloopfinishDispatcher(IProfilerSession* self, IStatus* status, ISC_TIMESTAMP_TZ timestamp) throw()
{
StatusType status2(status);
@ -20295,6 +20318,7 @@ namespace Firebird
virtual ISC_INT64 getId() = 0;
virtual unsigned getFlags() = 0;
virtual void cancel(StatusType* status) = 0;
virtual void finish(StatusType* status, ISC_TIMESTAMP_TZ timestamp) = 0;
virtual void defineStatement(StatusType* status, ISC_INT64 statementId, ISC_INT64 parentStatementId, const char* type, const char* packageName, const char* routineName, const char* sqlText) = 0;
virtual void defineRecordSource(ISC_INT64 statementId, unsigned cursorId, unsigned recSourceId, const char* accessPath, unsigned parentRecSourceId) = 0;

View File

@ -719,6 +719,7 @@ type
IProfilerPlugin_flushPtr = procedure(this: IProfilerPlugin; status: IStatus; transaction: ITransaction); cdecl;
IProfilerSession_getIdPtr = function(this: IProfilerSession): Int64; cdecl;
IProfilerSession_getFlagsPtr = function(this: IProfilerSession): Cardinal; cdecl;
IProfilerSession_cancelPtr = procedure(this: IProfilerSession; status: IStatus); cdecl;
IProfilerSession_finishPtr = procedure(this: IProfilerSession; status: IStatus; timestamp: ISC_TIMESTAMP_TZ); cdecl;
IProfilerSession_defineStatementPtr = procedure(this: IProfilerSession; status: IStatus; statementId: Int64; parentStatementId: Int64; type_: PAnsiChar; packageName: PAnsiChar; routineName: PAnsiChar; sqlText: PAnsiChar); cdecl;
IProfilerSession_defineRecordSourcePtr = procedure(this: IProfilerSession; statementId: Int64; cursorId: Cardinal; recSourceId: Cardinal; accessPath: PAnsiChar; parentRecSourceId: Cardinal); cdecl;
@ -3794,6 +3795,7 @@ type
ProfilerSessionVTable = class(DisposableVTable)
getId: IProfilerSession_getIdPtr;
getFlags: IProfilerSession_getFlagsPtr;
cancel: IProfilerSession_cancelPtr;
finish: IProfilerSession_finishPtr;
defineStatement: IProfilerSession_defineStatementPtr;
defineRecordSource: IProfilerSession_defineRecordSourcePtr;
@ -3814,6 +3816,7 @@ type
function getId(): Int64;
function getFlags(): Cardinal;
procedure cancel(status: IStatus);
procedure finish(status: IStatus; timestamp: ISC_TIMESTAMP_TZ);
procedure defineStatement(status: IStatus; statementId: Int64; parentStatementId: Int64; type_: PAnsiChar; packageName: PAnsiChar; routineName: PAnsiChar; sqlText: PAnsiChar);
procedure defineRecordSource(statementId: Int64; cursorId: Cardinal; recSourceId: Cardinal; accessPath: PAnsiChar; parentRecSourceId: Cardinal);
@ -3833,6 +3836,7 @@ type
procedure dispose(); virtual; abstract;
function getId(): Int64; virtual; abstract;
function getFlags(): Cardinal; virtual; abstract;
procedure cancel(status: IStatus); virtual; abstract;
procedure finish(status: IStatus; timestamp: ISC_TIMESTAMP_TZ); virtual; abstract;
procedure defineStatement(status: IStatus; statementId: Int64; parentStatementId: Int64; type_: PAnsiChar; packageName: PAnsiChar; routineName: PAnsiChar; sqlText: PAnsiChar); virtual; abstract;
procedure defineRecordSource(statementId: Int64; cursorId: Cardinal; recSourceId: Cardinal; accessPath: PAnsiChar; parentRecSourceId: Cardinal); virtual; abstract;
@ -8969,6 +8973,12 @@ begin
Result := ProfilerSessionVTable(vTable).getFlags(Self);
end;
procedure IProfilerSession.cancel(status: IStatus);
begin
ProfilerSessionVTable(vTable).cancel(Self, status);
FbException.checkException(status);
end;
procedure IProfilerSession.finish(status: IStatus; timestamp: ISC_TIMESTAMP_TZ);
begin
ProfilerSessionVTable(vTable).finish(Self, status, timestamp);
@ -15628,6 +15638,15 @@ begin
end
end;
procedure IProfilerSessionImpl_cancelDispatcher(this: IProfilerSession; status: IStatus); cdecl;
begin
try
IProfilerSessionImpl(this).cancel(status);
except
on e: Exception do FbException.catchException(status, e);
end
end;
procedure IProfilerSessionImpl_finishDispatcher(this: IProfilerSession; status: IStatus; timestamp: ISC_TIMESTAMP_TZ); cdecl;
begin
try
@ -16738,6 +16757,7 @@ initialization
IProfilerSessionImpl_vTable.dispose := @IProfilerSessionImpl_disposeDispatcher;
IProfilerSessionImpl_vTable.getId := @IProfilerSessionImpl_getIdDispatcher;
IProfilerSessionImpl_vTable.getFlags := @IProfilerSessionImpl_getFlagsDispatcher;
IProfilerSessionImpl_vTable.cancel := @IProfilerSessionImpl_cancelDispatcher;
IProfilerSessionImpl_vTable.finish := @IProfilerSessionImpl_finishDispatcher;
IProfilerSessionImpl_vTable.defineStatement := @IProfilerSessionImpl_defineStatementDispatcher;
IProfilerSessionImpl_vTable.defineRecordSource := @IProfilerSessionImpl_defineRecordSourceDispatcher;

View File

@ -52,6 +52,26 @@ IExternalResultSet* ProfilerPackage::flushProcedure(ThrowStatusExceptionWrapper*
return nullptr;
}
IExternalResultSet* ProfilerPackage::cancelSessionProcedure(ThrowStatusExceptionWrapper* /*status*/,
IExternalContext* context, const void* in, void* out)
{
const auto tdbb = JRD_get_thread_data();
const auto attachment = tdbb->getAttachment();
const auto transaction = tdbb->getTransaction();
const auto profilerManager = attachment->getProfilerManager(tdbb);
if (profilerManager->currentSession)
{
LogLocalStatus status("Profiler cancelSession");
profilerManager->currentSession->pluginSession->cancel(&status);
profilerManager->currentSession = nullptr;
}
return nullptr;
}
IExternalResultSet* ProfilerPackage::finishSessionProcedure(ThrowStatusExceptionWrapper* /*status*/,
IExternalContext* context, const FinishSessionInput::Type* in, void* out)
{
@ -456,6 +476,18 @@ ProfilerPackage::ProfilerPackage(MemoryPool& pool)
ODS_13_1,
// procedures
{
SystemProcedure(
pool,
"CANCEL_SESSION",
SystemProcedureFactory<VoidMessage, VoidMessage, cancelSessionProcedure>(),
prc_executable,
// input parameters
{
},
// output parameters
{
}
),
SystemProcedure(
pool,
"FINISH_SESSION",

View File

@ -128,6 +128,11 @@ private:
//----------
static Firebird::IExternalResultSet* cancelSessionProcedure(Firebird::ThrowStatusExceptionWrapper* status,
Firebird::IExternalContext* context, const void* in, void* out);
//----------
FB_MESSAGE(FinishSessionInput, Firebird::ThrowStatusExceptionWrapper,
(FB_BOOLEAN, flush)
);

View File

@ -151,6 +151,8 @@ public:
return FLAG_AFTER_EVENTS;
}
void cancel(ThrowStatusExceptionWrapper* status) override;
void finish(ThrowStatusExceptionWrapper* status, ISC_TIMESTAMP_TZ timestamp) override;
void defineStatement(ThrowStatusExceptionWrapper* status, SINT64 statementId, SINT64 parentStatementId,
@ -1166,6 +1168,20 @@ Session::Session(ThrowStatusExceptionWrapper* status, ProfilerPlugin* aPlugin, I
addRef();
}
void Session::cancel(ThrowStatusExceptionWrapper* status)
{
for (unsigned sessionIdx = 0; sessionIdx < plugin->sessions.getCount(); ++sessionIdx)
{
const auto& session = plugin->sessions[sessionIdx];
if (session.getPtr() == this)
{
plugin->sessions.remove(sessionIdx);
break;
}
}
}
void Session::finish(ThrowStatusExceptionWrapper* status, ISC_TIMESTAMP_TZ timestamp)
{
dirty = true;