⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 drivermanager.cc

📁 COPE the first practical network coding scheme which is developped on click
💻 CC
字号:
// -*- c-basic-offset: 4; related-file-name: "../../include/click/standard/drivermanager.hh" -*-/* * drivermanager.{cc,hh} -- element manages router driver stopping * Eddie Kohler * * Copyright (c) 2001 International Computer Science Institute * Copyright (c) 2001 Mazu Networks, Inc. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, subject to the conditions * listed in the Click LICENSE file. These conditions include: you must * preserve this copyright notice, and you cannot mention the copyright * holders in advertising related to the Software without their permission. * The Software is provided WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED. This * notice is a summary of the Click LICENSE file; the license in that file is * legally binding. */#include <click/config.h>#include <click/standard/drivermanager.hh>#include <click/confparse.hh>#include <click/error.hh>#include <click/router.hh>#include <click/straccum.hh>#include <click/handlercall.hh>CLICK_DECLSDriverManager::DriverManager()    : _timer(this){}DriverManager::~DriverManager(){}voidDriverManager::add_insn(int insn, int arg, int arg2, const String &arg3){    // first instruction must be WAIT or WAIT_STOP, so add INITIAL if    // necessary    if (_insns.size() == 0 && insn > INSN_WAIT_TIME)	add_insn(INSN_INITIAL, 0);    _insns.push_back(insn);    _args.push_back(arg);    _args2.push_back(arg2);    _args3.push_back(arg3);}intDriverManager::configure(Vector<String> &conf, ErrorHandler *errh){    if (router()->attachment("DriverManager"))	return errh->error("router has more than one DriverManager element");    router()->set_attachment("DriverManager", this);    _check_handlers = true;    if (cp_va_parse_remove_keywords(conf, 0, this, errh, "CHECK_HANDLERS", cpBool, "check handlers for correctness?", &_check_handlers, cpEnd) < 0)	return -1;        int before = errh->nerrors();    for (int i = 0; i < conf.size(); i++) {	String insn_name = cp_pop_spacevec(conf[i]);	if (!insn_name)		// ignore as benign	    /* nada */;	else if (!cp_keyword(insn_name, &insn_name))	    errh->error("missing or bad instruction name; should be 'INSNNAME [ARG]'");    	else if (insn_name == "wait_stop" || insn_name == "wait_pause"		 || (insn_name == "wait" && !conf[i])) {	    unsigned n = 1;	    if (!conf[i] || cp_unsigned(conf[i], &n))		add_insn(INSN_WAIT_STOP, n, 0);	    else		errh->error("expected '%s [COUNT]'", insn_name.c_str());	} else if (insn_name == "write" || insn_name == "call") {	    add_insn(INSN_WRITE, 0, 0, conf[i]);	} else if (insn_name == "write_skip") {	    add_insn(INSN_WRITE_SKIP, 0, 0, conf[i]);	} else if (insn_name == "read" || insn_name == "print") {	    add_insn(INSN_READ, 0, 0, conf[i]);#if CLICK_USERLEVEL || CLICK_TOOL	} else if (insn_name == "save" || insn_name == "append") {	    Vector<String> args;	    cp_spacevec(conf[i], args);	    String filename;	    if (args.size() >= 2 && cp_filename(args.back(), &filename)) {		args.pop_back();		add_insn((insn_name == "save" ? INSN_SAVE : INSN_APPEND), 0, 0, filename + " " + cp_unspacevec(args));	    } else		errh->error("expected '%s ELEMENT.HANDLER FILE'", insn_name.c_str());#endif	    	} else if (insn_name == "wait_time" || insn_name == "wait_for" || insn_name == "wait") {	    Timestamp ts;	    if (cp_time(conf[i], &ts))		add_insn(INSN_WAIT_TIME, ts.sec(), ts.subsec());	    else		errh->error("expected '%s TIME'", insn_name.cc());	} else if (insn_name == "stop" || insn_name == "quit") {	    if (!conf[i]) {		if (i < conf.size() - 1)		    errh->warning("arguments after '%s' ignored", insn_name.cc());		add_insn(INSN_STOP, 0);	    } else		errh->error("expected '%s'", insn_name.cc());#if CLICK_USERLEVEL || CLICK_TOOL	} else if (insn_name == "loop") {	    if (!conf[i])		add_insn(INSN_GOTO, 0);	    else		errh->error("expected '%s'", insn_name.cc());#endif	} else	    errh->error("unknown instruction '%s'", insn_name.cc());    }    if (_insns.size() == 0)	add_insn(INSN_WAIT_STOP, 1, 0);    add_insn(INSN_STOP, 0);    return (errh->nerrors() == before ? 0 : -1);}intDriverManager::initialize(ErrorHandler *errh){    if (!_check_handlers)	errh = ErrorHandler::silent_handler();    int before = errh->nerrors();        // process 'read' and 'write' instructions    for (int i = 0; i < _insns.size(); i++) {	int flags;	String extra;	switch (_insns[i]) {	  case INSN_WRITE:	  case INSN_WRITE_SKIP:	    flags = HandlerCall::CHECK_WRITE;	    goto parse;	  case INSN_READ:	    flags = HandlerCall::CHECK_READ;	    goto parse;#if CLICK_USERLEVEL || CLICK_TOOL	  case INSN_SAVE:	  case INSN_APPEND:	    extra = cp_pop_spacevec(_args3[i]) + " ";	    flags = HandlerCall::CHECK_READ;	    goto parse;#endif	  parse: {		HandlerCall hc(_args3[i]);		if (hc.initialize(flags, this, errh) >= 0) {		    _args[i] = hc.element()->eindex();		    _args2[i] = (intptr_t) (hc.handler());		    _args3[i] = extra + hc.value();		} else		    _insns[i] = INSN_IGNORE;		break;	    }	}    }    _insn_pos = 0;    _stopped_count = 0;    _timer.initialize(this);    int insn = _insns[_insn_pos];    assert(insn <= INSN_WAIT_TIME);    if (insn == INSN_WAIT_TIME)	_timer.schedule_after(Timestamp(_args[_insn_pos], _args2[_insn_pos]));    else if (insn == INSN_INITIAL)	// get rid of the initial runcount so we get called right away	router()->adjust_runcount(-1);    return (errh->nerrors() == before || !_check_handlers ? 0 : -1);}boolDriverManager::step_insn(){    _insn_pos++;    int insn = _insns[_insn_pos];    // change insn if appropriate    if (insn == INSN_WRITE_SKIP && router()->runcount() >= 0)	insn = INSN_WRITE;    switch (insn) {      case INSN_WRITE: {	  StringAccum sa;	  Element *e = router()->element(_args[_insn_pos]);	  const Handler *h = (const Handler*) _args2[_insn_pos];	  sa << "While calling '" << h->unparse_name(e) << "' from " << declaration() << ":";	  ContextErrorHandler cerrh(ErrorHandler::default_handler(), sa.take_string());	  h->call_write(_args3[_insn_pos], e, &cerrh);	  return true;      }      case INSN_READ: {	  Element *e = router()->element(_args[_insn_pos]);	  const Handler *h = (const Handler*) _args2[_insn_pos];	  ErrorHandler *errh = ErrorHandler::default_handler();	  String result = h->call_read(e, _args3[_insn_pos], errh);	  errh->message("%s:\n%s\n", h->unparse_name(e).cc(), result.cc());	  return true;      }#if CLICK_USERLEVEL || CLICK_TOOL      case INSN_SAVE:      case INSN_APPEND: {	  Element *e = router()->element(_args[_insn_pos]);	  const Handler *h = (const Handler*) _args2[_insn_pos];	  StringAccum sa;	  sa << "While calling '" << h->unparse_name(e) << "' from " << declaration() << ":";	  ContextErrorHandler cerrh(ErrorHandler::default_handler(), sa.take_string());	  String arg = _args3[_insn_pos];	  String filename = cp_pop_spacevec(arg);	  String result = h->call_read(e, arg, &cerrh);	  FILE *f;	  if (filename == "-")	      f = stdout;	  else if (!(f = fopen(filename.c_str(), (insn == INSN_SAVE ? "wb" : "ab")))) {	      cerrh.error("%s: %s", filename.c_str(), strerror(errno));	      return true;	  }	  fwrite(result.data(), 1, result.length(), f);	  if (f != stdout)	      fclose(f);	  return true;      }      case INSN_GOTO:	// reset intervening instructions	for (int i = _args[_insn_pos]; i < _insn_pos; i++)	    if (_insns[i] == INSN_WAIT_STOP)		_args2[i] = 0;	_insn_pos = _args[_insn_pos] - 1;	return true;#endif      case INSN_WRITE_SKIP:      case INSN_IGNORE:	return true;      case INSN_STOP:	router()->adjust_runcount(-1);	return false;      case INSN_WAIT_TIME:	_timer.schedule_after(Timestamp(_args[_insn_pos], _args2[_insn_pos]));	return false;      case INSN_WAIT_STOP:      default:	return false;    }}boolDriverManager::handle_stopped_driver(){    _stopped_count++;    // process current instruction    int insn = _insns[_insn_pos];    assert(insn == INSN_STOP || insn == INSN_WAIT_STOP || insn == INSN_WAIT_TIME || insn == INSN_INITIAL);    if (insn == INSN_STOP)	return false;    else if (insn == INSN_WAIT_STOP && _args2[_insn_pos] < _args[_insn_pos]) {	router()->adjust_runcount(1);	_args2[_insn_pos]++;	if (_args2[_insn_pos] < _args[_insn_pos])	    return true;    } else if (insn == INSN_WAIT_TIME)	_timer.unschedule();    else if (insn == INSN_INITIAL)	router()->adjust_runcount(1);    // process following instructions    while (step_insn())	/* nada */;    return true;}voidDriverManager::run_timer(){    // called when a timer expires    assert(_insns[_insn_pos] == INSN_WAIT_TIME);    while (step_insn())	/* nada */;}CLICK_ENDDECLSEXPORT_ELEMENT(DriverManager)ELEMENT_HEADER(<click/standard/drivermanager.hh>)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -