X-Git-Url: http://www.project-moonshot.org/gitweb/?a=blobdiff_plain;f=odbc-store%2Fodbc-store.cpp;h=1ad49a28c5246c58d7d253266a2a65696d672799;hb=3417a211ed16e6a30d4ed3bb62087880858e8a37;hp=48bbe8ef700c7dff1e278f16fb3bf9b00715a5d7;hpb=b766b9fa7005530d14a491dac86edddf5253c636;p=shibboleth%2Fcpp-sp.git diff --git a/odbc-store/odbc-store.cpp b/odbc-store/odbc-store.cpp index 48bbe8e..1ad49a2 100644 --- a/odbc-store/odbc-store.cpp +++ b/odbc-store/odbc-store.cpp @@ -332,24 +332,40 @@ ODBCStorageService::ODBCStorageService(const DOMElement* e) : m_log(Category::ge e = XMLHelper::getNextSiblingElement(e, RetryOnError); while (e) { if (e->hasChildNodes()) { - m_retries.push_back(XMLString::parseInt(e->getTextContent())); - m_log.info("will retry operations when native ODBC error (%ld) is returned", m_retries.back()); + try { + int code = XMLString::parseInt(e->getTextContent()); + m_retries.push_back(code); + m_log.info("will retry operations when native ODBC error (%d) is returned", code); + } + catch (XMLException&) { + m_log.error("skipping non-numeric ODBC retry code"); + } } e = XMLHelper::getNextSiblingElement(e, RetryOnError); } - // Initialize the cleanup thread - shutdown_wait.reset(CondWait::create()); - cleanup_thread = Thread::create(&cleanup_fn, (void*)this); + if (m_cleanupInterval > 0) { + // Initialize the cleanup thread + shutdown_wait.reset(CondWait::create()); + cleanup_thread = Thread::create(&cleanup_fn, (void*)this); + } + else { + m_log.info("no cleanup interval configured, no cleanup thread will be started"); + } } ODBCStorageService::~ODBCStorageService() { shutdown = true; - shutdown_wait->signal(); - cleanup_thread->join(nullptr); - if (m_henv != SQL_NULL_HANDLE) + if (shutdown_wait.get()) { + shutdown_wait->signal(); + } + if (cleanup_thread) { + cleanup_thread->join(nullptr); + } + if (m_henv != SQL_NULL_HANDLE) { SQLFreeHandle(SQL_HANDLE_ENV, m_henv); + } } pair ODBCStorageService::log_error(SQLHANDLE handle, SQLSMALLINT htype, const char* checkfor) @@ -507,8 +523,16 @@ bool ODBCStorageService::createRow(const char* table, const char* context, const } m_log.error("insert record failed (t=%s, c=%s, k=%s)", table, context, key); logres = log_error(stmt, SQL_HANDLE_STMT, "23000"); - if (logres.second) - return false; // supposedly integrity violation? + if (logres.second) { + // Supposedly integrity violation. + // Try and delete any expired record still hanging around until the final attempt. + if (attempts > 0) { + reap(table, context); + logres.first = true; // force it to treat as a retryable error + continue; + } + return false; + } } while (attempts && logres.first); throw IOException("ODBC StorageService failed to insert record.");