Beispiel #1
0
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, &parameters);

    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);
}
Beispiel #2
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;
}

}}}
Beispiel #3
0
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));
}