zeek/src/Event.h
Robin Sommer c8dfdb4492 Merge remote-tracking branch 'origin/topic/robin/interpreter-exceptions'
* origin/topic/robin/interpreter-exceptions:
  Adding test for new error handling.
  Experimental code to better handle interpreter errors.

This seems to work fine and it catches some potentially nasty crashes
so I'm merging it in even though it's not the final word on error
handling yet. #646 tracks the work scheduled for later.
2011-10-21 10:35:32 -07:00

135 lines
2.8 KiB
C++

// See the file "COPYING" in the main distribution directory for copyright.
#ifndef event_h
#define event_h
#include "EventRegistry.h"
#include "Serializer.h"
#include "AnalyzerTags.h"
class EventMgr;
class Event : public BroObj {
public:
Event(EventHandlerPtr handler, val_list* args,
SourceID src = SOURCE_LOCAL, AnalyzerID aid = 0,
TimerMgr* mgr = 0, BroObj* obj = 0);
~Event();
void SetNext(Event* n) { next_event = n; }
Event* NextEvent() const { return next_event; }
SourceID Source() const { return src; }
AnalyzerID Analyzer() const { return aid; }
TimerMgr* Mgr() const { return mgr; }
void Describe(ODesc* d) const;
protected:
friend class EventMgr;
// This method is protected to make sure that everybody goes through
// EventMgr::Dispatch().
void Dispatch(bool no_remote = false)
{
if ( event_serializer )
{
SerialInfo info(event_serializer);
event_serializer->Serialize(&info, handler->Name(), args);
}
if ( handler->ErrorHandler() )
reporter->BeginErrorHandler();
try
{
handler->Call(args, no_remote);
}
catch ( InterpreterException& e )
{
// Already reported.
}
if ( obj )
// obj->EventDone();
Unref(obj);
if ( handler->ErrorHandler() )
reporter->EndErrorHandler();
}
EventHandlerPtr handler;
val_list* args;
SourceID src;
AnalyzerID aid;
TimerMgr* mgr;
BroObj* obj;
Event* next_event;
};
extern int num_events_queued;
extern int num_events_dispatched;
class EventMgr : public BroObj {
public:
EventMgr();
~EventMgr();
void QueueEvent(EventHandlerPtr h, val_list* vl,
SourceID src = SOURCE_LOCAL, AnalyzerID aid = 0,
TimerMgr* mgr = 0, BroObj* obj = 0)
{
if ( h )
QueueEvent(new Event(h, vl, src, aid, mgr, obj));
else
delete_vals(vl);
}
void Dispatch();
void Dispatch(Event* event, bool no_remote = false)
{
current_src = event->Source();
event->Dispatch(no_remote);
Unref(event);
}
void Drain();
bool IsDraining() const { return draining; }
int HasEvents() const { return head != 0; }
// Returns the source ID of last raised event.
SourceID CurrentSource() const { return current_src; }
// Returns the ID of the analyzer which raised the last event, or 0 if
// non-analyzer event.
AnalyzerID CurrentAnalyzer() const { return current_aid; }
// Returns the timer mgr associated with the last raised event.
TimerMgr* CurrentTimerMgr() const { return current_mgr; }
int Size() const
{ return num_events_queued - num_events_dispatched; }
// Returns a peer record describing the local Bro.
RecordVal* GetLocalPeerVal();
void Describe(ODesc* d) const;
protected:
void QueueEvent(Event* event);
Event* head;
Event* tail;
SourceID current_src;
AnalyzerID current_aid;
TimerMgr* current_mgr;
RecordVal* src_val;
bool draining;
};
extern EventMgr mgr;
#endif