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. |