[Click] Problem with Timers

Angelo Colucci coluccister at gmail.com
Thu Feb 5 14:44:19 EST 2009


Hello,
Sorry in advance for my english.
I'm making for my thesis a module in click at the kernel level which
implements the link managment process,
according to the draft 802.11s.
This process associates a link instance for each link that each mesh STA
wants to establish/close with its peer.
This process allocate (remove) a link instance when it receives (sends ) an
open (close) frame from (to) its peer.
Each link instance is protected with a timer.
I write a test code in which a Machine element mantains MyNullEntry vector
(in the future LinkInstanceEntry).
Each MyNullEntry allocate its timer which, when expires, must invoke a
Machine method that handles the event.

 At the userlevel I incountered this problem (produced inside
reschedule_after() method):

click: ../lib/timer.cc:236: void Timer::schedule_at(const Timestamp&):
Assertion `_router && initialized()'   failed.
Aborted


I have installed Ubuntu with 2.6.19.2, executed in VirtualBox, for Kernel
test. At this level, even if  reschedule_after() is commented,
click_chatter output  doesn't appear and the O.S goes in deadloak.


//machine.hh

typedef Vector<MyNullEntry*> vector;
typedef vector::iterator mc_iter;

class Machine : public Element {
    vector _vector;
    int32_t _n_entry;
    int32_t _count;
    bool _started_timers;

public: ...
};

//machine.cc

int Machine::initialize(ErrorHandler* errh){
    click_chatter("initialize machine: _n_entry = %d\n", _n_entry);
    for(int i = 0; i < 5; i++){
        click_chatter("initialize %d\n", i);
        MyNullEntry *pnue = 0;

        pnue = new MyNullEntry();
        if(!pnue){
            click_chatter("MyNullEntry: new error\n");
            return -1;
        }
        pnue->set_state(ACTIVE);
        pnue->set_timerType(RTRY);
        pnue->set_element_ptr(this);
        pnue->initialize(errh);
        add_entry(pnue);   //this method invokes _vector.push_back(pnue);
    }
    return 0;
}


void Machine::push(int, Packet* p){
    click_chatter("start push\n");
    if(!_started_timers){
        for(int i = 0; i < 5; i++){
            Timer* pt = _vector.at(i)->get_timer();
            pt->reschedule_after_sec(3);
            //_vector.at(i)->run_timer(pt);
        }
        _started_timers = true;
    }
    output(0).push(p);
    _count++;
    click_chatter("end push\n");

}

//mynullentry.hh

enum timer_set{
    RTRY,
    CNF,
    HLD
};

enum state {ACTIVE, INACTIVE};
class MyNullEntry : public Element {
private:
    state  _state;
    Timer* _timer;
    MyNullEntry* _me;
    Machine* _mc;            //points to my container
    timer_set _timer_type;
    MyNullEntry(const MyNullEntry&);
public: ...
};

//mynullentry.cc


MyNullEntry::MyNullEntry(){
    _timer = 0;
    _me = this;
}

int MyNullEntry::initialize(ErrorHandler* errh){
    click_chatter("initialize MyNullEntry\n");
    _timer = new Timer(this);
    if(!_timer){
        click_chatter("Timer: new error\n");
        return -1;
    }
    _timer->initialize(this);
    return 0;
}

void MyNullEntry::run_timer(Timer* timer){
    click_chatter("run_timer\n");
    assert(timer == _timer);
    // don't run if the timer is scheduled (an upstream queue went empty but
we
    // don't care)
    if(_timer->scheduled())
        return;
    switch(_timer_type){
        case(RTRY):
            expire_r();
            break;
        case(CNF):
            expire_c();
            break;
        case(HLD):
            expire_h();
            break;
        default:
            assert(0);
        }
    //_timer->schedule_after_msec(2500);

}

void MyNullEntry::expire_r(){
    click_chatter("Retry Timer\n");
   //s a stupid tentative to verify that each link instance
   //can communicate the event to Machine
    _mc->print_table();
 }


Anyone can advice me if this use of Timer is wrong in any case?
Someone may suggest an alternative?


Thanks in advance for any kind of help.
Angelo


More information about the click mailing list