Merge remote-tracking branch 'origin/master' into topic/jsiwek/gh-893-intrusive-ptr-migration

This commit is contained in:
Jon Siwek 2020-05-21 14:44:55 -07:00
commit 2cbf36721c
35 changed files with 594 additions and 387 deletions

View file

@ -26,14 +26,6 @@ using namespace std;
using threading::Value;
using threading::Field;
static void delete_value_ptr_array(Value** vals, int num_fields)
{
for ( int i = 0; i < num_fields; ++i )
delete vals[i];
delete [] vals;
}
/**
* InputHashes are used as Dictionaries to store the value and index hashes
* for all lines currently stored in a table. Index hash is stored as
@ -1091,7 +1083,7 @@ void Manager::SendEntry(ReaderFrontend* reader, Value* *vals)
else
assert(false);
delete_value_ptr_array(vals, readFields);
Value::delete_value_ptr_array(vals, readFields);
}
int Manager::SendEntryTable(Stream* i, const Value* const *vals)
@ -1458,7 +1450,7 @@ void Manager::Put(ReaderFrontend* reader, Value* *vals)
else
assert(false);
delete_value_ptr_array(vals, readFields);
Value::delete_value_ptr_array(vals, readFields);
}
int Manager::SendEventStreamEvent(Stream* i, EnumVal* type, const Value* const *vals)
@ -1762,7 +1754,7 @@ bool Manager::Delete(ReaderFrontend* reader, Value* *vals)
return false;
}
delete_value_ptr_array(vals, readVals);
Value::delete_value_ptr_array(vals, readVals);
return success;
}
@ -1787,68 +1779,6 @@ bool Manager::CallPred(Func* pred_func, const int numvals, ...) const
return result;
}
// Raise everything in here as warnings so it is passed to scriptland without
// looking "fatal". In addition to these warnings, ReaderBackend will queue
// one reporter message.
bool Manager::SendEvent(ReaderFrontend* reader, const string& name, const int num_vals, Value* *vals) const
{
Stream *i = FindStream(reader);
if ( i == nullptr )
{
reporter->InternalWarning("Unknown reader %s in SendEvent for event %s", reader->Name(), name.c_str());
delete_value_ptr_array(vals, num_vals);
return false;
}
EventHandler* handler = event_registry->Lookup(name);
if ( handler == nullptr )
{
Warning(i, "Event %s not found", name.c_str());
delete_value_ptr_array(vals, num_vals);
return false;
}
#ifdef DEBUG
DBG_LOG(DBG_INPUT, "SendEvent for event %s with %d vals",
name.c_str(), num_vals);
#endif
const auto& type = handler->GetType()->Params();
int num_event_vals = type->NumFields();
if ( num_vals != num_event_vals )
{
Warning(i, "Wrong number of values for event %s", name.c_str());
delete_value_ptr_array(vals, num_vals);
return false;
}
bool convert_error = false;
zeek::Args vl;
vl.reserve(num_vals);
for ( int j = 0; j < num_vals; j++)
{
Val* v = ValueToVal(i, vals[j], convert_error);
vl.emplace_back(AdoptRef{}, v);
if ( v && ! convert_error && ! same_type(type->GetFieldType(j).get(), v->GetType().get()) )
{
convert_error = true;
type->GetFieldType(j)->Error("SendEvent types do not match", v->GetType().get());
}
}
delete_value_ptr_array(vals, num_vals);
if ( convert_error )
return false;
else if ( handler )
mgr.Enqueue(handler, std::move(vl), SOURCE_LOCAL);
return true;
}
void Manager::SendEvent(EventHandlerPtr ev, const int numvals, ...) const
{
zeek::Args vl;
@ -2228,9 +2158,9 @@ HashKey* Manager::HashValues(const int num_elements, const Value* const *vals) c
}
// convert threading value to Bro value
// have_error is a reference to a boolean which is set to true as soon as an error occured.
// have_error is a reference to a boolean which is set to true as soon as an error occurs.
// When have_error is set to true at the beginning of the function, it is assumed that
// an error already occured in the past and processing is aborted.
// an error already occurred in the past and processing is aborted.
Val* Manager::ValueToVal(const Stream* i, const Value* val, BroType* request_type, bool& have_error) const
{
if ( have_error )
@ -2383,204 +2313,6 @@ Val* Manager::ValueToVal(const Stream* i, const Value* val, BroType* request_typ
return nullptr;
}
Val* Manager::ValueToVal(const Stream* i, const Value* val, bool& have_error) const
{
if ( have_error )
return nullptr;
if ( ! val->present )
return nullptr; // unset field
switch ( val->type ) {
case TYPE_BOOL:
return val_mgr->Bool(val->val.int_val)->Ref();
case TYPE_INT:
return val_mgr->Int(val->val.int_val).release();
case TYPE_COUNT:
case TYPE_COUNTER:
return val_mgr->Count(val->val.int_val).release();
case TYPE_DOUBLE:
case TYPE_TIME:
case TYPE_INTERVAL:
return new Val(val->val.double_val, val->type);
case TYPE_STRING:
{
BroString *s = new BroString((const u_char*)val->val.string_val.data, val->val.string_val.length, true);
return new StringVal(s);
}
case TYPE_PORT:
return val_mgr->Port(val->val.port_val.port, val->val.port_val.proto)->Ref();
case TYPE_ADDR:
{
IPAddr* addr = nullptr;
switch ( val->val.addr_val.family ) {
case IPv4:
addr = new IPAddr(val->val.addr_val.in.in4);
break;
case IPv6:
addr = new IPAddr(val->val.addr_val.in.in6);
break;
default:
assert(false);
}
AddrVal* addrval = new AddrVal(*addr);
delete addr;
return addrval;
}
case TYPE_SUBNET:
{
IPAddr* addr = nullptr;
switch ( val->val.subnet_val.prefix.family ) {
case IPv4:
addr = new IPAddr(val->val.subnet_val.prefix.in.in4);
break;
case IPv6:
addr = new IPAddr(val->val.subnet_val.prefix.in.in6);
break;
default:
assert(false);
}
SubNetVal* subnetval = new SubNetVal(*addr, val->val.subnet_val.length);
delete addr;
return subnetval;
}
case TYPE_PATTERN:
{
RE_Matcher* re = new RE_Matcher(val->val.pattern_text_val);
re->Compile();
return new PatternVal(re);
}
case TYPE_TABLE:
{
IntrusivePtr<TypeList> set_index;
if ( val->val.set_val.size == 0 && val->subtype == TYPE_VOID )
// don't know type - unspecified table.
set_index = make_intrusive<TypeList>();
else
{
// all entries have to have the same type...
TypeTag stag = val->subtype;
if ( stag == TYPE_VOID )
TypeTag stag = val->val.set_val.vals[0]->type;
IntrusivePtr<BroType> index_type;
if ( stag == TYPE_ENUM )
{
// Enums are not a base-type, so need to look it up.
const auto& sv = val->val.set_val.vals[0]->val.string_val;
std::string enum_name(sv.data, sv.length);
const auto& enum_id = global_scope()->Find(enum_name);
if ( ! enum_id )
{
Warning(i, "Value '%s' for stream '%s' is not a valid enum.",
enum_name.data(), i->name.c_str());
have_error = true;
return nullptr;
}
index_type = enum_id->GetType();
}
else
index_type = base_type(stag);
set_index = make_intrusive<TypeList>(index_type);
set_index->Append(std::move(index_type));
}
auto s = make_intrusive<SetType>(std::move(set_index), nullptr);
TableVal* t = new TableVal(std::move(s));
for ( int j = 0; j < val->val.set_val.size; j++ )
{
Val* assignval = ValueToVal(i, val->val.set_val.vals[j], have_error);
t->Assign({AdoptRef{}, assignval}, nullptr);
}
return t;
}
case TYPE_VECTOR:
{
IntrusivePtr<BroType> type;
if ( val->val.vector_val.size == 0 && val->subtype == TYPE_VOID )
// don't know type - unspecified table.
type = base_type(TYPE_ANY);
else
{
// all entries have to have the same type...
if ( val->subtype == TYPE_VOID )
type = base_type(val->val.vector_val.vals[0]->type);
else
type = base_type(val->subtype);
}
auto vt = make_intrusive<VectorType>(std::move(type));
auto v = make_intrusive<VectorVal>(std::move(vt));
for ( int j = 0; j < val->val.vector_val.size; j++ )
v->Assign(j, ValueToVal(i, val->val.vector_val.vals[j], have_error));
return v.release();
}
case TYPE_ENUM: {
// Convert to string first to not have to deal with missing
// \0's...
string enum_string(val->val.string_val.data, val->val.string_val.length);
// let's try looking it up by global ID.
auto id = lookup_ID(enum_string.c_str(), GLOBAL_MODULE_NAME);
if ( ! id || ! id->IsEnumConst() )
{
Warning(i, "Value '%s' for stream '%s' is not a valid enum.",
enum_string.c_str(), i->name.c_str());
have_error = true;
return nullptr;
}
EnumType* t = id->GetType()->AsEnumType();
int intval = t->Lookup(id->ModuleName(), id->Name());
if ( intval < 0 )
{
Warning(i, "Enum value '%s' for stream '%s' not found.",
enum_string.c_str(), i->name.c_str());
have_error = true;
return nullptr;
}
auto rval = t->GetVal(intval);
return rval.release();
}
default:
reporter->InternalError("Unsupported type for input_read in stream %s", i->name.c_str());
}
assert(false);
return nullptr;
}
Manager::Stream* Manager::FindStream(const string &name) const
{
for ( auto s = readers.begin(); s != readers.end(); ++s )

View file

@ -118,7 +118,6 @@ protected:
friend class PutMessage;
friend class DeleteMessage;
friend class ClearMessage;
friend class SendEventMessage;
friend class SendEntryMessage;
friend class EndCurrentSendMessage;
friend class ReaderClosedMessage;
@ -142,11 +141,6 @@ protected:
void SendEntry(ReaderFrontend* reader, threading::Value* *vals);
void EndCurrentSend(ReaderFrontend* reader);
// Allows readers to directly send Bro events. The num_vals and vals
// must be the same the named event expects. Takes ownership of
// threading::Value fields.
bool SendEvent(ReaderFrontend* reader, const std::string& name, const int num_vals, threading::Value* *vals) const;
// Instantiates a new ReaderBackend of the given type (note that
// doing so creates a new thread!).
ReaderBackend* CreateBackend(ReaderFrontend* frontend, EnumVal* tag);
@ -227,14 +221,9 @@ private:
// startpos.
int CopyValue(char *data, const int startpos, const threading::Value* val) const;
// Convert Threading::Value to an internal Bro Type (works also with
// Records).
// Convert Threading::Value to an internal Bro Type (works with Records).
Val* ValueToVal(const Stream* i, const threading::Value* val, BroType* request_type, bool& have_error) const;
// Convert Threading::Value to an internal Bro type just using the information given in the threading::Value.
// This allows more flexibility, especially given structures in script-land that contain any types.
Val* ValueToVal(const Stream* i, const threading::Value* val, bool& have_error) const;
// Convert Threading::Value to an internal Bro list type.
Val* ValueToIndexVal(const Stream* i, int num_fields, const RecordType* type, const threading::Value* const *vals, bool& have_error) const;

View file

@ -54,30 +54,6 @@ public:
private:
};
class SendEventMessage final : public threading::OutputMessage<ReaderFrontend> {
public:
SendEventMessage(ReaderFrontend* reader, const char* name, const int num_vals, Value* *val)
: threading::OutputMessage<ReaderFrontend>("SendEvent", reader),
name(copy_string(name)), num_vals(num_vals), val(val) {}
~SendEventMessage() override { delete [] name; }
bool Process() override
{
bool success = input_mgr->SendEvent(Object(), name, num_vals, val);
if ( ! success )
reporter->Error("SendEvent for event %s failed", name);
return true; // We do not want to die if sendEvent fails because the event did not return.
}
private:
const char* name;
const int num_vals;
Value* *val;
};
class ReaderErrorMessage final : public threading::OutputMessage<ReaderFrontend>
{
public:
@ -229,11 +205,6 @@ void ReaderBackend::Clear()
SendOut(new ClearMessage(frontend));
}
void ReaderBackend::SendEvent(const char* name, const int num_vals, Value* *vals)
{
SendOut(new SendEventMessage(frontend, name, num_vals, vals));
}
void ReaderBackend::EndCurrentSend()
{
SendOut(new EndCurrentSendMessage(frontend));

View file

@ -280,18 +280,6 @@ protected:
*/
virtual bool DoHeartbeat(double network_time, double current_time) = 0;
/**
* Method allowing a reader to send a specified Bro event. Vals must
* match the values expected by the bro event.
*
* @param name name of the bro event to send
*
* @param num_vals number of entries in \a vals
*
* @param vals the values to be given to the event
*/
void SendEvent(const char* name, const int num_vals, threading::Value* *vals);
// Content-sending-functions (simple mode). Include table-specific
// functionality that simply is not used if we have no table.