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

Don't leak memory after conversion to blob for store the value in a variable or parameter

This commit is contained in:
asfernandes 2007-03-24 03:00:22 +00:00
parent 9c326ffb8b
commit 032a4b170c
4 changed files with 40 additions and 10 deletions

View File

@ -2443,10 +2443,6 @@ static void move_from_string(thread_db* tdbb, const dsc* from_desc, dsc* to_desc
ULONG blob_temp_id = blob->blb_temp_id; ULONG blob_temp_id = blob->blb_temp_id;
BLB_move(tdbb, &blob_desc, to_desc, field); BLB_move(tdbb, &blob_desc, to_desc, field);
// finish if we're just moving values in descriptors
if (!field || field->nod_type != nod_field)
return;
// 14-June-2004. Nickolay Samofatov // 14-June-2004. Nickolay Samofatov
// The code below saves a lot of memory when bunches of records are // The code below saves a lot of memory when bunches of records are
// converted to blobs from strings. If BLB_move is materialized blob we // converted to blobs from strings. If BLB_move is materialized blob we
@ -2479,9 +2475,14 @@ static void move_from_string(thread_db* tdbb, const dsc* from_desc, dsc* to_desc
} }
else { else {
// But even in bad case when we cannot free blob immediately // But even in bad case when we cannot free blob immediately
// we may still bind lifetime of blob to current request. // we may still bind lifetime of blob to current top level request.
if (!current->bli_request) { if (!current->bli_request)
current->bli_request = tdbb->tdbb_request; {
jrd_req* blob_request = tdbb->tdbb_request;
while (blob_request->req_caller)
blob_request = blob_request->req_caller;
current->bli_request = blob_request;
current->bli_request->req_blobs.add(blob_temp_id); current->bli_request->req_blobs.add(blob_temp_id);
} }
} }

View File

@ -660,7 +660,8 @@ void EXE_receive(thread_db* tdbb,
jrd_req* request, jrd_req* request,
USHORT msg, USHORT msg,
USHORT length, USHORT length,
UCHAR* buffer) UCHAR* buffer,
bool top_level)
{ {
/************************************** /**************************************
* *
@ -738,6 +739,34 @@ void EXE_receive(thread_db* tdbb,
else else
MOVE_FASTER((SCHAR *) request + message->nod_impure, buffer, length); MOVE_FASTER((SCHAR *) request + message->nod_impure, buffer, length);
// ASF: temporary blobs returned to the client should not be released
// with the request, but in the transaction end.
if (top_level)
{
for (int i = 0; i < format->fmt_count; ++i)
{
const DSC* desc = &format->fmt_desc[i];
if (desc->isBlob())
{
const bid* id = (bid*)
((UCHAR*)request + message->nod_impure + (ULONG)(IPTR)desc->dsc_address);
if (transaction->tra_blobs.locate(id->bid_temp_id()))
{
BlobIndex* current = &transaction->tra_blobs.current();
if (current->bli_request &&
current->bli_request->req_blobs.locate(id->bid_temp_id()))
{
current->bli_request->req_blobs.fastRemove();
current->bli_request = NULL;
}
}
}
}
}
execute_looper(tdbb, request, transaction, jrd_req::req_proceed); execute_looper(tdbb, request, transaction, jrd_req::req_proceed);
} //try } //try

View File

@ -35,7 +35,7 @@ namespace Jrd {
void EXE_assignment(Jrd::thread_db*, Jrd::jrd_nod*); void EXE_assignment(Jrd::thread_db*, Jrd::jrd_nod*);
void EXE_execute_db_triggers(Jrd::thread_db*, Jrd::jrd_tra*, enum Jrd::jrd_req::req_ta); void EXE_execute_db_triggers(Jrd::thread_db*, Jrd::jrd_tra*, enum Jrd::jrd_req::req_ta);
Jrd::jrd_req* EXE_find_request(Jrd::thread_db*, Jrd::jrd_req*, bool); Jrd::jrd_req* EXE_find_request(Jrd::thread_db*, Jrd::jrd_req*, bool);
void EXE_receive(Jrd::thread_db*, Jrd::jrd_req*, USHORT, USHORT, UCHAR*); void EXE_receive(Jrd::thread_db*, Jrd::jrd_req*, USHORT, USHORT, UCHAR*, bool = false);
void EXE_send(Jrd::thread_db*, Jrd::jrd_req*, USHORT, USHORT, const UCHAR*); void EXE_send(Jrd::thread_db*, Jrd::jrd_req*, USHORT, USHORT, const UCHAR*);
void EXE_start(Jrd::thread_db*, Jrd::jrd_req*, Jrd::jrd_tra*); void EXE_start(Jrd::thread_db*, Jrd::jrd_req*, Jrd::jrd_tra*);
void EXE_unwind(Jrd::thread_db*, Jrd::jrd_req*); void EXE_unwind(Jrd::thread_db*, Jrd::jrd_req*);

View File

@ -3179,7 +3179,7 @@ ISC_STATUS GDS_RECEIVE(ISC_STATUS * user_status,
#endif #endif
EXE_receive(tdbb, request, msg_type, msg_length, EXE_receive(tdbb, request, msg_type, msg_length,
reinterpret_cast<UCHAR*>(msg)); reinterpret_cast<UCHAR*>(msg), true);
check_autocommit(request, tdbb); check_autocommit(request, tdbb);