On 03/14/2016 06:36 PM, Volodymyr Tarasenko wrote:
Hi,
get_err_buffer uses thread specific buffer. Internally it uses pthread_getspecific. In a few words it returns NULL if it called from the wrong thread.
So, looks like you have called OraclePreparedStatement_getLastError from incorrect thread. It should be called from the same thread where prepared statement was initialed.
Hope it helps.
Good luck, Volodymyr!
Seems like pthread_setspecific() is to be called on a per-thread basis to allocate a separate buffer for each thread. Right now pthread_setspecific() is called only once by the thread that initializes the key.
/* Allocate the key */ static void error_msg_key_alloc() { pthread_key_create(&error_msg_key, free); pthread_setspecific(error_msg_key, malloc(STRLEN)); }
/* This is a general error function also used in OracleResultSet */ const char *OraclePreparedStatement_getLastError(int err, OCIError > *errhp) { sb4 errcode; char* erb; pthread_once(&error_msg_key_once, error_msg_key_alloc); erb = get_err_buffer(); assert(erb);
should become something like:
/* Allocate the key */ static void error_msg_key_alloc() { pthread_key_create(&error_msg_key, free); }
/* This is a general error function also used in OracleResultSet */ const char *OraclePreparedStatement_getLastError(int err, OCIError > *errhp) { sb4 errcode; char* erb; pthread_once(&error_msg_key_once, error_msg_key_alloc); if (pthread_getspecific(error_msg_key) == NULL) { pthread_setspecific(error_msg_key, calloc(1, STRLEN)); } erb = get_err_buffer(); assert(erb);
See http://www.ibm.com/support/knowledgecenter/SSLTBW_2.1.0/com.ibm.zos.v2r1.bpx... and http://apiexamples.com/c/pthread/pthread_setspecific.html#L0
I'll prepare a pull-request.