Re: [opendbx] /dev/urandom file descritpors left open, libopendbx-devel Digest, Vol 49, Issue 1
Brought to you by:
nose
|
From: Levine, A. <AL...@gl...> - 2014-01-28 18:09:47
|
Norbert,
BTW, I ran 1,000,000 rapid fire select statements yesterday using a global/static
OpenDBX::Conn object and did not crash. As stated when using a global object
only one /dev/urandom file descriptor is opened and left open.
Regarding Conn::finish() the
Test function with crash on Result::~Result() is below.
void TestMsSqlGetAllTxFileTransmissions()
{
// Norbert, if this object is declared here then each call to this function
// leaves a /dev/urandom file descriptor open. Making it global leaves only
// a single file descriptor open.
#ifndef USE_GLOBAL_DB_OBJECT
OpenDBX::Conn GetAllTxFileDb;
#endif
PTR_COLUMN_NAME_POS_PAIR pNameCol = NULL;
try
{
GetAllTxFileDb = Conn( "mssql", "172.16.232.60", "" );
GetAllTxFileDb.bind("MediaServerTest1", "test1admin", "ponyexpress", ODBX_BIND_SIMPLE );
std::cout << "Initialized connection" << std::endl;
}
catch( std::exception &e )
{
std::cerr << "Caught exception: " << e.what() << std::endl;
return;
}
OpenDBX::Result DbRslt = GetAllTxFileDb.create( DbStoredProcGetAllSchedFileTransmissions ).execute();
odbxres RsltStat;
int RowCnt = 0;
while( ( RsltStat = DbRslt.getResult() ) != ODBX_RES_DONE )
{
// used to map column names and positions
pNameCol = NULL;
switch( RsltStat )
{
case ODBX_RES_TIMEOUT:
// NOTE: Retrieving the result is not (!) canceled
continue;
case ODBX_RES_NOROWS:
continue;
// case ODBX_RES_ROWS:
default:
break;
}
while(DbRslt.getRow() != ODBX_ROW_DONE )
{
if((DbRslt.columnCount() > 0) && (DbRslt.fieldLength(0) > 0))
{
if(DbRslt.columnName(0).c_str()[0] == '@')
{
std::cout << "\nPRINTING STATUS TABLE\n";
// Processing a return/status "table" not the desired data table
if(pNameCol == NULL)
{
pNameCol = (PTR_COLUMN_NAME_POS_PAIR)&gAllSchFileTxStatusMap;
// first time through map the column names and positions
FillColNamePosPairs(DbRslt, pNameCol, (sizeof(DB_ALL_SCHED_FILE_TX_STATUS_MAPPINGS)/sizeof(COLUMN_NAME_POS_PAIR)));
}
// Just print it out for example
if((gAllSchFileTxStatusMap.ReturnValue.Pos != -1) && (DbRslt.fieldLength(gAllSchFileTxStatusMap.ReturnValue.Pos) != 0))
{
std::cout << gAllSchFileTxStatusMap.ReturnValue.Name << ": "
<< DbRslt.fieldValue(gAllSchFileTxStatusMap.ReturnValue.Pos) << std::endl;
}
else
{
std::cout << gAllSchFileTxStatusMap.ReturnValue.Name << ":" << endl;
}
if((gAllSchFileTxStatusMap.StatusText.Pos != -1) && (DbRslt.fieldLength(gAllSchFileTxStatusMap.StatusText.Pos) != 0))
{
// Just print it out
std::cout << gAllSchFileTxStatusMap.StatusText.Name << ": "
<< DbRslt.fieldValue(gAllSchFileTxStatusMap.StatusText.Pos) << std::endl;
}
else
{
std::cout << gAllSchFileTxStatusMap.StatusText.Name << ":" << endl;
}
}
else
{
// Getting the "main" desired table
std::cout << "\nPRINTING DESIRED TABLE ROW INDEX " << RowCnt++ << std::endl;
if(pNameCol == NULL)
{
pNameCol = (PTR_COLUMN_NAME_POS_PAIR)&gAllSchFileTxMap;
// first time through map the column names and positions
FillColNamePosPairs(DbRslt, pNameCol, (sizeof(DB_ALL_SCHED_FILE_TX_MAPPINGS)/sizeof(COLUMN_NAME_POS_PAIR)));
}
// Just print it out for this example
if((gAllSchFileTxMap.FileId.Pos != -1) && (DbRslt.fieldLength(gAllSchFileTxMap.FileId.Pos) != 0))
{
std::cout << gAllSchFileTxMap.FileId.Name << ": "
<< DbRslt.fieldValue(gAllSchFileTxMap.FileId.Pos) << endl;
}
if((gAllSchFileTxMap.ScheduleId.Pos != -1) && (DbRslt.fieldLength(gAllSchFileTxMap.ScheduleId.Pos) != 0))
{
std::cout << gAllSchFileTxMap.ScheduleId.Name << ": "
<< DbRslt.fieldValue(gAllSchFileTxMap.ScheduleId.Pos) << endl;
}
}
}
} // while ( DbRslt.getRow() != ODBX_ROW_DONE )
} // while( ( RsltStat = DbRslt.getResult() ) != ODBX_RES_DONE )
try
{
DbRslt.finish();
}
catch( std::exception &e )
{
std::cerr << "Caught exception: " << e.what() << std::endl;
return;
}
try
{
GetAllTxFileDb.unbind();
}
catch( std::exception &e )
{
std::cerr << "Caught exception: " << e.what() << std::endl;
return;
}
// Norbert, if we call finish(), then when function exits Result::~Result()
// crashes application as seg fault on the delete m_impl statement
// try
// {
// GetAllTxFileDb.finish();
// }
// catch( std::exception &e )
// {
// std::cerr << "Caught exception: " << e.what() << std::endl;
// return;
// }
return;
}
Regards,
Adam
Hi Adam
> When we call Result::finish(), Conn::unbind(), Conn::finish() all
> three calls complete correctly, When the function is exited the
> OpenDBX::Result object goes out of scope and the destructor is
> called. In the destructor, OpenDBX::~Result(), the delete m_impl;
> crashes the application with a segmentation fault, I assume because
> the m_impl was already deleted in Conn::finish()?
The sequence of calls is correct.
Conn::finish() doesn't free any memory allocated in m_impl (which are
different across all object types, so Conn, Stmt and Result all use
their own m_impl variable with their own object types like Conn_Impl,
StmtSimple_Impl and Result_Impl).
I would assume that there might be a problem with the reference
counting. Do you use assignment for Result or the copy contructor like
Result result = myresult?
Norbert
____________________________________________________________
This e-mail (including attached documents) may contain confidential or proprietary
information intended only for use by the named recipient(s). Use by persons
other than the named recipient(s), further dissemination, or copying of this
email is prohibited unless authorized by the sender.
|