int main(int argc, char **argv) { struct time_type time; ZOOM_connection *z; ZOOM_resultset *r; int *elc; struct event_line_t *els; ZOOM_options o; int i; int k; init_statics(); read_params(argc, argv, ¶meters); z = (ZOOM_connection *) xmalloc(sizeof(*z) * parameters.concurrent); r = (ZOOM_resultset *) xmalloc(sizeof(*r) * parameters.concurrent); elc = (int *) xmalloc(sizeof(*elc) * parameters.concurrent * parameters.repeat); els = (struct event_line_t *) xmalloc( sizeof(*els) * parameters.concurrent * parameters.repeat * 10); o = ZOOM_options_create(); /* async mode */ ZOOM_options_set (o, "async", "1"); /* get first record of result set (using piggypack) */ if (parameters.piggypack) ZOOM_options_set (o, "count", "1"); /* set proxy */ if (strlen(parameters.proxy)) ZOOM_options_set (o, "proxy", parameters.proxy); /* preferred record syntax */ if (0){ ZOOM_options_set (o, "preferredRecordSyntax", "usmarc"); ZOOM_options_set (o, "elementSetName", "F"); } time_init(&time); /* repeat loop */ for (k = 0; k < parameters.repeat; k++){ /* progress zeroing */ for (i = 0; i < 4096; i++){ parameters.progress[i] = k * 5 -1; } /* connect to all concurrent connections*/ for ( i = 0; i < parameters.concurrent; i++){ /* set event count to zero */ elc[k * parameters.concurrent + i] = 0; /* create connection - pass options (they are the same for all) */ z[i] = ZOOM_connection_create(o); /* connect and init */ ZOOM_connection_connect(z[i], parameters.host, 0); } /* search all */ for (i = 0; i < parameters.concurrent; i++) r[i] = ZOOM_connection_search_pqf (z[i], parameters.query); /* network I/O. pass number of connections and array of connections */ while ((i = ZOOM_event (parameters.concurrent, z))){ int event = ZOOM_connection_last_event(z[i-1]); const char *errmsg; const char *addinfo; int error = 0; //int progress = zoom_progress[event]; if (event == ZOOM_EVENT_SEND_DATA || event == ZOOM_EVENT_RECV_DATA) continue; time_stamp(&time); /* updating events and event list */ error = ZOOM_connection_error(z[i-1] , &errmsg, &addinfo); if (error) parameters.progress[i] = zoom_progress[ZOOM_EVENT_UNKNOWN]; //parameters.progress[i] = zoom_progress[ZOOM_EVENT_NONE]; else if (event == ZOOM_EVENT_CONNECT) parameters.progress[i] = zoom_progress[event]; else //parameters.progress[i] = zoom_progress[event]; parameters.progress[i] += 1; update_events(elc, els, k, i-1, time_sec(&time), time_usec(&time), parameters.progress[i], event, zoom_events[event], error, errmsg); } /* destroy connections */ for (i = 0; i<parameters.concurrent; i++) { ZOOM_resultset_destroy (r[i]); ZOOM_connection_destroy (z[i]); } } /* for (k = 0; k < parameters.repeat; k++) repeat loop */ /* output */ if (parameters.gnuplot){ printf("# gnuplot data and instruction file \n"); printf("# gnuplot thisfile \n"); printf("\n"); printf("set title \"Z39.50 connection plot\"\n"); printf("set xlabel \"Connection\"\n"); printf("set ylabel \"Time Seconds\"\n"); printf("set zlabel \"Progress\"\n"); printf("set ticslevel 0\n"); printf("set grid\n"); printf("set pm3d\n"); printf("splot '-' using ($1):($2):($3) t '' with points\n"); printf("\n"); printf("\n"); } print_table_header(); print_events(elc, els, parameters.concurrent); if (parameters.gnuplot){ printf("end\n"); printf("pause -1 \"Hit ENTER to return\"\n"); } /* destroy data structures and exit */ xfree(z); xfree(r); xfree(elc); xfree(els); ZOOM_options_destroy(o); exit (0); }
namespace journal { #define AIO_CMPL_TIMEOUT_SEC 5 #define AIO_CMPL_TIMEOUT_NSEC 0 #define FINAL_AIO_CMPL_TIMEOUT_SEC 15 #define FINAL_AIO_CMPL_TIMEOUT_NSEC 0 // Static timespec jcntl::_aio_cmpl_timeout; ///< Timeout for blocking libaio returns timespec jcntl::_final_aio_cmpl_timeout; ///< Timeout for blocking libaio returns when stopping or finalizing bool jcntl::_init = init_statics(); bool jcntl::init_statics() { _aio_cmpl_timeout.tv_sec = AIO_CMPL_TIMEOUT_SEC; _aio_cmpl_timeout.tv_nsec = AIO_CMPL_TIMEOUT_NSEC; _final_aio_cmpl_timeout.tv_sec = FINAL_AIO_CMPL_TIMEOUT_SEC; _final_aio_cmpl_timeout.tv_nsec = FINAL_AIO_CMPL_TIMEOUT_NSEC; return true; } // Functions jcntl::jcntl(const std::string& jid, const std::string& jdir, JournalLog& jrnl_log): _jid(jid), _jdir(jdir), _init_flag(false), _stop_flag(false), _readonly_flag(false), _jrnl_log(jrnl_log), _linearFileController(*this), _emptyFilePoolPtr(0), _emap(), _tmap(), _wmgr(this, _emap, _tmap, _linearFileController), _recoveryManager(_jdir.dirname(), _jid, _emap, _tmap, jrnl_log) {} jcntl::~jcntl() { if (_init_flag && !_stop_flag) try { stop(true); } catch (const jexception& e) { std::cerr << e << std::endl; } _linearFileController.finalize(); } void jcntl::initialize(EmptyFilePool* efpp, const uint16_t wcache_num_pages, const uint32_t wcache_pgsize_sblks, aio_callback* const cbp) { _init_flag = false; _stop_flag = false; _readonly_flag = false; _emap.clear(); _tmap.clear(); _linearFileController.finalize(); _jdir.clear_dir(); // Clear any existing journal files _linearFileController.initialize(_jdir.dirname(), efpp, 0ULL); _linearFileController.getNextJournalFile(); _wmgr.initialize(cbp, wcache_pgsize_sblks, wcache_num_pages, QLS_WMGR_MAXDTOKPP, QLS_WMGR_MAXWAITUS, 0); _init_flag = true; } void jcntl::recover(EmptyFilePoolManager* efpmp, const uint16_t wcache_num_pages, const uint32_t wcache_pgsize_sblks, aio_callback* const cbp, const std::vector<std::string>* prep_txn_list_ptr, uint64_t& highest_rid) { _init_flag = false; _stop_flag = false; _readonly_flag = false; _emap.clear(); _tmap.clear(); _linearFileController.finalize(); // Verify journal dir and journal files _jdir.verify_dir(); _recoveryManager.analyzeJournals(prep_txn_list_ptr, efpmp, &_emptyFilePoolPtr); assert(_emptyFilePoolPtr != 0); highest_rid = _recoveryManager.getHighestRecordId(); _jrnl_log.log(/*LOG_DEBUG*/JournalLog::LOG_INFO, _jid, _recoveryManager.toString(_jid, 5U)); _linearFileController.initialize(_jdir.dirname(), _emptyFilePoolPtr, _recoveryManager.getHighestFileNumber()); _recoveryManager.setLinearFileControllerJournals(&qpid::linearstore::journal::LinearFileController::addJournalFile, &_linearFileController); if (_recoveryManager.isLastFileFull()) { _linearFileController.getNextJournalFile(); } _wmgr.initialize(cbp, wcache_pgsize_sblks, wcache_num_pages, QLS_WMGR_MAXDTOKPP, QLS_WMGR_MAXWAITUS, (_recoveryManager.isLastFileFull() ? 0 : _recoveryManager.getEndOffset())); _readonly_flag = true; _init_flag = true; } void jcntl::recover_complete() { if (!_readonly_flag) throw jexception(jerrno::JERR_JCNTL_NOTRECOVERED, "jcntl", "recover_complete"); _recoveryManager.recoveryComplete(); _readonly_flag = false; } void jcntl::delete_jrnl_files() { stop(true); // wait for AIO to complete _linearFileController.purgeEmptyFilesToEfp(); _jdir.delete_dir(); } iores jcntl::enqueue_data_record(const void* const data_buff, const std::size_t tot_data_len, const std::size_t this_data_len, data_tok* dtokp, const bool transient) { iores r; check_wstatus("enqueue_data_record"); { slock s(_wr_mutex); while (handle_aio_wait(_wmgr.enqueue(data_buff, tot_data_len, this_data_len, dtokp, 0, 0, false, transient, false), r, dtokp)) ; } return r; } iores jcntl::enqueue_extern_data_record(const std::size_t tot_data_len, data_tok* dtokp, const bool transient) { iores r; check_wstatus("enqueue_extern_data_record"); { slock s(_wr_mutex); while (handle_aio_wait(_wmgr.enqueue(0, tot_data_len, 0, dtokp, 0, 0, false, transient, true), r, dtokp)) ; } return r; } iores jcntl::enqueue_txn_data_record(const void* const data_buff, const std::size_t tot_data_len, const std::size_t this_data_len, data_tok* dtokp, const std::string& xid, const bool tpc_flag, const bool transient) { iores r; check_wstatus("enqueue_tx_data_record"); { slock s(_wr_mutex); while (handle_aio_wait(_wmgr.enqueue(data_buff, tot_data_len, this_data_len, dtokp, xid.data(), xid.size(), tpc_flag, transient, false), r, dtokp)) ; } return r; } iores jcntl::enqueue_extern_txn_data_record(const std::size_t tot_data_len, data_tok* dtokp, const std::string& xid, const bool tpc_flag, const bool transient) { iores r; check_wstatus("enqueue_extern_txn_data_record"); { slock s(_wr_mutex); while (handle_aio_wait(_wmgr.enqueue(0, tot_data_len, 0, dtokp, xid.data(), xid.size(), tpc_flag, transient, true), r, dtokp)) ; } return r; } iores jcntl::read_data_record(void** const datapp, std::size_t& dsize, void** const xidpp, std::size_t& xidsize, bool& transient, bool& external, data_tok* const dtokp, bool ignore_pending_txns) { check_rstatus("read_data"); if (_recoveryManager.readNextRemainingRecord(datapp, dsize, xidpp, xidsize, transient, external, dtokp, ignore_pending_txns)) { return RHM_IORES_SUCCESS; } return RHM_IORES_EMPTY; } iores jcntl::dequeue_data_record(data_tok* const dtokp, const bool txn_coml_commit) { iores r; check_wstatus("dequeue_data"); { slock s(_wr_mutex); while (handle_aio_wait(_wmgr.dequeue(dtokp, 0, 0, false, txn_coml_commit), r, dtokp)) ; } return r; } iores jcntl::dequeue_txn_data_record(data_tok* const dtokp, const std::string& xid, const bool tpc_flag, const bool txn_coml_commit) { iores r; check_wstatus("dequeue_data"); { slock s(_wr_mutex); while (handle_aio_wait(_wmgr.dequeue(dtokp, xid.data(), xid.size(), tpc_flag, txn_coml_commit), r, dtokp)) ; } return r; } iores jcntl::txn_abort(data_tok* const dtokp, const std::string& xid) { iores r; check_wstatus("txn_abort"); { slock s(_wr_mutex); while (handle_aio_wait(_wmgr.abort(dtokp, xid.data(), xid.size()), r, dtokp)) ; } return r; } iores jcntl::txn_commit(data_tok* const dtokp, const std::string& xid) { iores r; check_wstatus("txn_commit"); { slock s(_wr_mutex); while (handle_aio_wait(_wmgr.commit(dtokp, xid.data(), xid.size()), r, dtokp)) ; } return r; } bool jcntl::is_txn_synced(const std::string& xid) { slock s(_wr_mutex); bool res = _wmgr.is_txn_synced(xid); return res; } int32_t jcntl::get_wr_events(timespec* const timeout) { stlock t(_wr_mutex); if (!t.locked()) return jerrno::LOCK_TAKEN; return _wmgr.get_events(timeout, false); } void jcntl::stop(const bool block_till_aio_cmpl) { if (_readonly_flag) check_rstatus("stop"); else check_wstatus("stop"); _stop_flag = true; if (!_readonly_flag) flush(block_till_aio_cmpl); } LinearFileController& jcntl::getLinearFileControllerRef() { return _linearFileController; } // static std::string jcntl::str2hexnum(const std::string& str) { if (str.empty()) { return "<null>"; } std::ostringstream oss; oss << "(" << str.size() << ")0x" << std::hex; for (unsigned i=str.size(); i>0; --i) { oss << std::setfill('0') << std::setw(2) << (uint16_t)(uint8_t)str[i-1]; } return oss.str(); } iores jcntl::flush(const bool block_till_aio_cmpl) { if (!_init_flag) return RHM_IORES_SUCCESS; if (_readonly_flag) throw jexception(jerrno::JERR_JCNTL_READONLY, "jcntl", "flush"); iores res; { slock s(_wr_mutex); res = _wmgr.flush(); } if (block_till_aio_cmpl) aio_cmpl_wait(); return res; } // Protected/Private functions void jcntl::check_wstatus(const char* fn_name) const { if (!_init_flag) throw jexception(jerrno::JERR__NINIT, "jcntl", fn_name); if (_readonly_flag) throw jexception(jerrno::JERR_JCNTL_READONLY, "jcntl", fn_name); if (_stop_flag) throw jexception(jerrno::JERR_JCNTL_STOPPED, "jcntl", fn_name); } void jcntl::check_rstatus(const char* fn_name) const { if (!_init_flag) throw jexception(jerrno::JERR__NINIT, "jcntl", fn_name); if (_stop_flag) throw jexception(jerrno::JERR_JCNTL_STOPPED, "jcntl", fn_name); } void jcntl::aio_cmpl_wait() { //while (_wmgr.get_aio_evt_rem()) while (true) { uint32_t aer; { slock s(_wr_mutex); aer = _wmgr.get_aio_evt_rem(); } if (aer == 0) break; // no events left if (get_wr_events(&_aio_cmpl_timeout) == jerrno::AIO_TIMEOUT) throw jexception(jerrno::JERR_JCNTL_AIOCMPLWAIT, "jcntl", "aio_cmpl_wait"); } } bool jcntl::handle_aio_wait(const iores res, iores& resout, const data_tok* dtp) { resout = res; if (res == RHM_IORES_PAGE_AIOWAIT) { while (_wmgr.curr_pg_blocked()) { if (_wmgr.get_aio_evt_rem() == 0) { //std::cout << "&&&&&& jcntl::handle_aio_wait() " << _wmgr.status_str() << std::endl; // DEBUG throw jexception("_wmgr.curr_pg_blocked() with no events remaining"); // TODO - complete exception } if (_wmgr.get_events(&_aio_cmpl_timeout, false) == jerrno::AIO_TIMEOUT) { std::ostringstream oss; oss << "get_events() returned JERR_JCNTL_AIOCMPLWAIT; wmgr_status: " << _wmgr.status_str(); _jrnl_log.log(JournalLog::LOG_CRITICAL, _jid, oss.str()); throw jexception(jerrno::JERR_JCNTL_AIOCMPLWAIT, "jcntl", "handle_aio_wait"); } } return true; } else if (res == RHM_IORES_FILE_AIOWAIT) { // while (_wmgr.curr_file_blocked()) // { // if (_wmgr.get_events(pmgr::UNUSED, &_aio_cmpl_timeout) == jerrno::AIO_TIMEOUT) // { // std::ostringstream oss; // oss << "get_events() returned JERR_JCNTL_AIOCMPLWAIT; wmgr_status: " << _wmgr.status_str(); // this->log(LOG_CRITICAL, oss.str()); // throw jexception(jerrno::JERR_JCNTL_AIOCMPLWAIT, "jcntl", "handle_aio_wait"); // } // } // _wrfc.wr_reset(); resout = RHM_IORES_SUCCESS; data_tok::write_state ws = dtp->wstate(); return ws == data_tok::ENQ_PART || ws == data_tok::DEQ_PART || ws == data_tok::ABORT_PART || ws == data_tok::COMMIT_PART; } return false; } }}}
char * setlocale(int category, char *locale) { static char buf[MAXLOCALE*(MAXLOCALENAME + 1) + 1]; /* buffer for current LC_ALL value */ int nonuniform; short ret; char my_ctype[CTYPE_SIZE]; /* local copy */ struct lconv my_lconv; /* local copy */ char *my_lconv_numeric_str; char *my_lconv_monetary_str; int i; char *p; /* initialize my_lconv to lconv */ memcpy(&my_lconv, lconv, sizeof(my_lconv)); /* * Following code is to avoid static initialisation of * strings which would otherwise blow up "xstr". */ if (_locales[0][0] == '\0') init_statics(); if (locale == NULL) { if (category == LC_ALL) { /* * Assume all locales are set to the same value. Then * scan through the locales to see if any are * different. If they are the same, return the common * value; otherwise, construct a "composite" value. */ nonuniform = 0; /* assume all locales set the same */ for (i = 0; i < MAXLOCALE - 2; i++) { if (strcmp(_locales[i], _locales[i + 1]) != 0) { nonuniform = 1; break; } } if (nonuniform) { /* * They're not all the same. Construct a list * of all the locale values, in order, * separated by slashes. Return that value. */ (void) strcpy(buf, _locales[0]); for (i = 1; i < MAXLOCALE - 1; i++) { (void) strcat(buf, "/"); (void) strcat(buf, _locales[i]); } return (buf); } else { /* * They're all the same; any one you return is * OK. */ return (_locales[0]); } } else return (_locales[category - 1]); } switch (category) { case LC_ALL: if (strchr(locale, '/') != NULL) { /* * Composite value; extract each category. */ if (strlen(locale) > sizeof buf - 1) return (NULL); /* too long */ (void) strcpy(buf, locale); p = buf; /* * LC_CTYPE and LC_NUMERIC are set here. * Others locales won't be set here, * they will be just marked. */ for (i = 0; i < MAXLOCALE - 1; i++) { p = strtok(p, "/"); if (p == NULL) return (NULL); /* missing item */ switch (i) { case LC_CTYPE - 1: if (setlocale(LC_CTYPE,p) == NULL) return (NULL); break; case LC_NUMERIC - 1: if (setlocale(LC_NUMERIC,p) == NULL) return (NULL); break; case LC_TIME - 1: if (setlocale(LC_TIME,p) == NULL) return (NULL); break; case LC_MONETARY - 1: if (setlocale(LC_MONETARY,p) == NULL) return (NULL); break; case LANGINFO - 1: if (setlocale(LANGINFO,p) == NULL) return (NULL); break; case LC_COLLATE - 1: if (setlocale(LC_COLLATE,p) == NULL) return (NULL); break; case LC_MESSAGES - 1: if (setlocale(LC_MESSAGES,p) == NULL) return (NULL); break; } p = NULL; } if (strtok((char *)NULL, "/") != NULL) return (NULL); /* extra stuff at end */ } /* If category = LC_ALL, Drop through to test each individual * category, one at a time. Note default rules where env vars * are not set */ case LC_CTYPE: if ((ret = getlocale_ctype(locale , my_ctype, _locales[LC_CTYPE - 1])) < 0) return (NULL); if (ret) { (void) memcpy(_ctype_, my_ctype, CTYPE_SIZE/2); (void) memcpy(_ctype_ul, my_ctype+(CTYPE_SIZE/2), CTYPE_SIZE/2); } if (category != LC_ALL) break; case LC_NUMERIC: if ((my_lconv_numeric_str = getlocale_numeric(locale, &my_lconv, _locales[LC_NUMERIC - 1])) == NULL) return (NULL); if (*my_lconv_numeric_str) { if (lconv_numeric_str != NULL) free((malloc_t)lconv_numeric_str); lconv_numeric_str = my_lconv_numeric_str; memcpy(lconv, my_lconv, sizeof(my_lconv)); } if (category != LC_ALL) break; case LC_TIME: if ((ret = openlocale("LC_TIME", LC_TIME, locale, _locales[LC_TIME -1])) < 0) return (NULL); if (ret) (void) close(ret); if (category != LC_ALL) break; case LC_MONETARY: if ((my_lconv_monetary_str = getlocale_monetary(locale, &my_lconv, _locales[LC_MONETARY - 1])) == NULL) return (NULL); if (*my_lconv_monetary_str) { if (lconv_monetary_str != NULL) free((malloc_t)lconv_monetary_str); lconv_monetary_str = my_lconv_monetary_str; memcpy(lconv, &my_lconv, sizeof(my_lconv)); } if (category != LC_ALL) break; case LANGINFO: if ((ret = openlocale("LANGINFO", LANGINFO, locale, _locales[LANGINFO - 1])) < 0) { lang_succ = OFF; return (NULL); } if (ret) { lang_succ = OFF; (void) close(ret); } if (category != LC_ALL) break; case LC_COLLATE: if ((ret = openlocale("LC_COLLATE", LC_COLLATE, locale, _locales[LC_COLLATE - 1])) < 0) return (NULL); if (ret) { (void) close(ret); } if (category != LC_ALL) break; case LC_MESSAGES: if ((ret = openlocale("LC_MESSAGES", LC_MESSAGES, locale, _locales[LC_MESSAGES - 1])) < 0) return (NULL); if (ret) { (void) close(ret); } } return (setlocale(category, (char *)NULL)); }