23 #include <blackboard/internal/interface_manager.h> 25 #include <blackboard/blackboard.h> 26 #include <blackboard/internal/memory_manager.h> 27 #include <blackboard/internal/message_manager.h> 28 #include <blackboard/exceptions.h> 29 #include <blackboard/internal/interface_mem_header.h> 30 #include <blackboard/interface_listener.h> 31 #include <blackboard/interface_observer.h> 32 #include <blackboard/internal/instance_factory.h> 33 #include <blackboard/internal/notifier.h> 35 #include <interface/interface.h> 36 #include <interface/interface_info.h> 38 #include <core/threading/mutex.h> 39 #include <core/threading/mutex_locker.h> 40 #include <core/threading/refc_rwlock.h> 41 #include <core/exceptions/system.h> 42 #include <utils/system/dynamic_module/module.h> 43 #include <utils/time/time.h> 73 notifier = bb_notifier;
79 writer_interfaces.clear();
88 delete instance_factory;
103 BlackBoardInterfaceManager::new_interface_instance(
const char *type,
const char *identifier,
const char *owner)
107 iface->set_instance_serial(next_instance_serial());
108 iface->set_mediators(
this, msgmgr);
109 if (owner) iface->set_owner(owner);
122 BlackBoardInterfaceManager::delete_interface_instance(
Interface *interface)
124 if (owner_info_.find(interface->
uid()) != owner_info_.end()) {
125 OwnerInfo &info = owner_info_[interface->
uid()];
127 if (info.writer == interface) {
131 info.readers.remove(interface);
144 BlackBoardInterfaceManager::find_interface_in_memory(
const char *type,
const char *identifier)
148 for ( cit = memmgr->
begin(); cit != memmgr->
end(); ++cit ) {
150 if ( (strncmp(ih->
type, type, __INTERFACE_TYPE_SIZE) == 0) &&
151 (strncmp(ih->
id, identifier, __INTERFACE_ID_SIZE) == 0)
166 BlackBoardInterfaceManager::next_mem_serial()
168 unsigned int serial = 1;
171 for ( cit = memmgr->
begin(); cit != memmgr->
end(); ++cit ) {
173 if ( ih->
serial >= serial ) {
186 BlackBoardInterfaceManager::next_instance_serial()
190 return instance_serial++;
208 BlackBoardInterfaceManager::create_interface(
const char *type,
const char *identifier,
215 interface = new_interface_instance(type, identifier, owner);
220 e.
append(
"BlackBoardInterfaceManager::createInterface: interface of type %s could not be created", type);
227 strncpy(ih->
type, type, __INTERFACE_TYPE_SIZE);
228 strncpy(ih->
id, identifier, __INTERFACE_ID_SIZE);
229 memcpy(ih->
hash, interface->
hash(), __INTERFACE_HASH_SIZE);
232 ih->
serial = next_mem_serial();
255 if (strlen(type) > __INTERFACE_TYPE_SIZE) {
256 throw Exception(
"Interface type '%s' too long, maximum length is %zu",
257 type, __INTERFACE_TYPE_SIZE);
259 if (strlen(identifier) > __INTERFACE_ID_SIZE) {
260 throw Exception(
"Interface ID '%s' too long, maximum length is %zu",
261 type, __INTERFACE_ID_SIZE);
268 bool created =
false;
272 ptr = find_interface_in_memory(type, identifier);
277 iface = new_interface_instance(type, identifier, owner);
279 if ( (iface->
hash_size() != __INTERFACE_HASH_SIZE ) ||
280 (memcmp(iface->
hash(), ih->
hash, __INTERFACE_HASH_SIZE) != 0) ) {
284 rwlocks[ih->
serial]->ref();
287 create_interface(type, identifier, owner, iface, ptr);
291 owner_info_[iface->
uid()].readers.push_back(iface);
292 iface->set_readwrite(
false, rwlocks[ih->
serial]);
305 if (iface) delete_interface_instance(iface);
328 std::list<Interface *>
330 const char *id_pattern,
336 std::list<Interface *> rv;
343 for ( cit = memmgr->
begin(); cit != memmgr->
end(); ++cit ) {
348 char type[__INTERFACE_TYPE_SIZE + 1];
349 char id[__INTERFACE_ID_SIZE + 1];
350 type[__INTERFACE_TYPE_SIZE] = 0;
351 id[__INTERFACE_TYPE_SIZE] = 0;
352 strncpy(type, ih->
type, __INTERFACE_TYPE_SIZE);
353 strncpy(
id, ih->
id, __INTERFACE_ID_SIZE);
355 if ((fnmatch(type_pattern, type, 0) == FNM_NOMATCH) ||
356 (fnmatch(id_pattern,
id, 0) == FNM_NOMATCH) ) {
362 iface = new_interface_instance(ih->
type, ih->
id, owner);
365 if ( (iface->
hash_size() != __INTERFACE_HASH_SIZE ) ||
366 (memcmp(iface->
hash(), ih->
hash, __INTERFACE_HASH_SIZE) != 0) ) {
370 rwlocks[ih->
serial]->ref();
372 owner_info_[iface->
uid()].readers.push_back(iface);
373 iface->set_readwrite(
false, rwlocks[ih->
serial]);
383 for (std::list<Interface *>::iterator j = rv.begin(); j != rv.end(); ++j) {
389 if (iface) delete_interface_instance( iface );
390 for (std::list<Interface *>::iterator i = rv.begin(); i != rv.end(); ++i) {
391 delete_interface_instance(*i);
419 if (strlen(type) > __INTERFACE_TYPE_SIZE) {
420 throw Exception(
"Interface type '%s' too long, maximum length is %zu",
421 type, __INTERFACE_TYPE_SIZE);
423 if (strlen(identifier) > __INTERFACE_ID_SIZE) {
424 throw Exception(
"Interface ID '%s' too long, maximum length is %zu",
425 type, __INTERFACE_ID_SIZE);
434 bool created =
false;
437 ptr = find_interface_in_memory(type, identifier);
446 iface = new_interface_instance(type, identifier, owner);
447 if ( (iface->
hash_size() != __INTERFACE_HASH_SIZE ) ||
448 (memcmp(iface->
hash(), ih->
hash, __INTERFACE_HASH_SIZE) != 0) ) {
452 rwlocks[ih->
serial]->ref();
455 create_interface(type, identifier, owner, iface, ptr);
459 owner_info_[iface->
uid()].writer = iface;
460 iface->set_readwrite(
true, rwlocks[ih->
serial]);
465 writer_interfaces[ih->
serial] = iface;
474 if (iface) delete_interface_instance(iface);
490 if ( interface == NULL )
return;
492 bool destroyed =
false;
496 bool killed_writer = interface->__write_access;
499 if ( interface->__write_access ) {
500 writer_interfaces.erase( interface->__mem_serial );
502 memmgr->
free( interface->__mem_real_ptr );
505 if ( interface->__write_access ) {
507 writer_interfaces.erase( interface->__mem_serial );
524 delete_interface_instance( interface );
540 for ( cit = memmgr->
begin(); cit != memmgr->
end(); ++cit ) {
544 char type[__INTERFACE_TYPE_SIZE + 1];
545 char id[__INTERFACE_ID_SIZE + 1];
547 type[__INTERFACE_TYPE_SIZE] = 0;
548 id[__INTERFACE_ID_SIZE] = 0;
549 strncpy(type, ih->
type, __INTERFACE_TYPE_SIZE);
550 strncpy(
id, ih->
id, __INTERFACE_ID_SIZE);
551 std::string uid = std::string(type) +
"::" + id;
575 const char *id_pattern)
const 582 for ( cit = memmgr->
begin(); cit != memmgr->
end(); ++cit ) {
586 char type[__INTERFACE_TYPE_SIZE + 1];
587 char id[__INTERFACE_ID_SIZE + 1];
589 type[__INTERFACE_TYPE_SIZE] = 0;
590 id[__INTERFACE_ID_SIZE] = 0;
591 strncpy(type, ih->
type, __INTERFACE_TYPE_SIZE);
592 strncpy(
id, ih->
id, __INTERFACE_ID_SIZE);
593 if ((fnmatch(type_pattern, type, FNM_NOESCAPE) == 0) &&
594 (fnmatch(id_pattern,
id, FNM_NOESCAPE) == 0))
596 std::string uid = std::string(type) +
"::" + id;
617 BlackBoardInterfaceManager::writer_for_mem_serial(
unsigned int mem_serial)
619 if ( writer_interfaces.find(mem_serial) != writer_interfaces.end() ) {
620 return writer_interfaces[mem_serial];
622 char type[__INTERFACE_TYPE_SIZE + 1] =
"Unknown";
623 char id[__INTERFACE_ID_SIZE + 1] =
"Invalid";
625 type[__INTERFACE_TYPE_SIZE] = 0;
626 id[__INTERFACE_ID_SIZE] = 0;
627 std::string uid =
"Unknown::Invalid";
630 for ( cit = memmgr->
begin(); cit != memmgr->
end(); ++cit ) {
632 if (ih->
serial == mem_serial) {
633 strncpy(type, ih->
type, __INTERFACE_TYPE_SIZE);
634 strncpy(
id, ih->
id, __INTERFACE_ID_SIZE);
654 return (writer_interfaces.find(interface->__mem_serial) != writer_interfaces.end());
665 std::list<std::string>
668 std::list<std::string> rv;
671 if ((info = owner_info_.find(interface->
uid())) != owner_info_.end()) {
672 std::list<Interface *>::const_iterator i;
673 for (i = info->second.readers.begin(); i != info->second.readers.end(); ++i) {
674 rv.push_back((*i)->owner());
688 if ((info = owner_info_.find(interface->
uid())) != owner_info_.end()) {
689 if (info->second.writer) {
690 rv = info->second.writer->owner();
702 std::list<std::string>
705 std::list<std::string> rv;
708 if ((info = owner_info_.find(uid)) != owner_info_.end()) {
709 std::list<Interface *>::const_iterator i;
710 for (i = info->second.readers.begin(); i != info->second.readers.end(); ++i) {
711 rv.push_back((*i)->owner());
729 if ((info = owner_info_.find(uid)) != owner_info_.end()) {
730 if (info->second.writer) {
731 rv = info->second.writer->owner();
void notify_of_reader_added(const Interface *interface, unsigned int event_instance_serial)
Notify that reader has been added.
int64_t timestamp_sec
time in seconds since Unix epoch
Interface * new_interface_instance(const char *type, const char *identifier)
Creates a new interface instance.
BlackBoard instance factory.
ChunkIterator begin()
Get first element for chunk iteration.
unsigned int datasize() const
Get data size.
bool is_master() const
Check if this BB memory manager is the master.
void notify_of_interface_created(const char *type, const char *id)
Notify that an interface has been created.
void lock() const
Lock list.
void close(Interface *interface)
Close interface.
virtual std::string writer(const Interface *interface) const
Get writer of interface.
void notify_of_writer_added(const Interface *interface, unsigned int event_instance_serial)
Notify that writer has been added.
Fawkes library namespace.
ChunkIterator end()
Get end of chunk list.
void unlock()
Unlock the mutex.
BlackBoard memory manager.
virtual void notify_of_data_change(const Interface *interface)
Notify of data change.
A class for handling time.
void notify_of_writer_removed(const Interface *interface, unsigned int event_instance_serial)
Notify that writer has been removed.
void notify_of_data_change(const Interface *interface)
Notify of data change.
Base class for all Fawkes BlackBoard interfaces.
virtual ~BlackBoardInterfaceManager()
Destructor.
InterfaceInfoList * list(const char *type_pattern, const char *id_pattern) const
Get a constrained list of interfaces.
virtual unsigned int num_readers(const Interface *interface) const
Get number of readers.
Thrown if no writer interface is alive.
const unsigned char * hash() const
Get interface hash.
Interface * open_for_writing(const char *interface_type, const char *identifier, const char *owner=NULL)
Open interface for writing.
Interface information list.
BlackBoardInterfaceManager(BlackBoardMemoryManager *bb_memmgr, BlackBoardMessageManager *bb_msgmgr, BlackBoardNotifier *bb_notifier)
Constructor.
Base class for exceptions in Fawkes.
unsigned short serial() const
Get instance serial of interface.
void delete_interface_instance(Interface *interface)
Destroy an interface instance.
std::list< Interface * > open_multiple_for_reading(const char *type_pattern, const char *id_pattern="*", const char *owner=NULL)
Open all interfaces of the given type for reading.
void notify_of_interface_destroyed(const char *type, const char *id)
Notify that an interface has been destroyed.
int64_t timestamp_usec
additional time microseconds
Read/write lock with reference counting.
void unlock() const
Unlock list.
Timestamp data, must be present and first entries for each interface data structs! This leans on time...
Thrown if BlackBoard is not master and master operation has been requested.
const char * uid() const
Get unique identifier of interface.
size_t hash_size() const
Get size of interface hash.
Thrown if versions do not match.
void append(const char *type, const char *id, const unsigned char *hash, unsigned int serial, bool has_writer, unsigned int num_readers, const std::list< std::string > &readers, const std::string &writer, const Time ×tamp)
Append an interface info.
bool is_writer() const
Check if this is a writing instance.
Iterator for memory chunks.
virtual std::list< std::string > readers(const Interface *interface) const
Get owners of interfaces who opened for reading.
void unlock()
Unlock memory.
BlackBoard message manager.
void free(void *chunk_ptr)
Free a memory chunk.
Interface * open_for_reading(const char *interface_type, const char *identifier, const char *owner=NULL)
Open interface for reading.
InterfaceInfoList * list_all() const
Get a list of interfaces.
void lock()
Lock this mutex.
Thrown if a writer is already active on an interface that writing has been requested for...
Mutex mutual exclusion lock.
void notify_of_reader_removed(const Interface *interface, unsigned int event_instance_serial)
Notify that reader has been removed.
virtual bool exists_writer(const Interface *interface) const
Check if a writer exists for the given interface.
System ran out of memory and desired operation could not be fulfilled.
void append(const char *format,...)
Append messages to the message list.