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()];
126 if (interface->is_writer()) {
127 if (info.writer == interface) {
131 info.readers.remove(interface);
144 BlackBoardInterfaceManager::find_interface_in_memory(
const char *type,
const char *identifier)
146 interface_header_t *ih;
147 BlackBoardMemoryManager::ChunkIterator cit;
148 for ( cit = memmgr->
begin(); cit != memmgr->
end(); ++cit ) {
149 ih = (interface_header_t *)*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;
169 interface_header_t *ih;
170 BlackBoardMemoryManager::ChunkIterator cit;
171 for ( cit = memmgr->
begin(); cit != memmgr->
end(); ++cit ) {
172 ih = (interface_header_t *)*cit;
173 if ( ih->serial >= serial ) {
174 serial = ih->serial + 1;
186 BlackBoardInterfaceManager::next_instance_serial()
190 return instance_serial++;
192 throw BBNotMasterException(
"Instance serial can only be requested by BB Master");
208 BlackBoardInterfaceManager::create_interface(
const char *type,
const char *identifier,
210 Interface* &interface,
void* &ptr)
212 interface_header_t *ih;
215 interface = new_interface_instance(type, identifier, owner);
217 ptr = memmgr->alloc_nolock(interface->datasize() +
sizeof(interface_header_t));
218 ih = (interface_header_t *)ptr;
219 }
catch (OutOfMemoryException &e) {
220 e.append(
"BlackBoardInterfaceManager::createInterface: interface of type %s could not be created", type);
225 memset(ptr, 0, interface->datasize() +
sizeof(interface_header_t));
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();
233 ih->flag_writer_active = 0;
235 rwlocks[ih->serial] =
new RefCountRWLock();
237 interface->set_memory(ih->serial, ptr, (
char *)ptr +
sizeof(interface_header_t));
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";
629 BlackBoardMemoryManager::ChunkIterator cit;
630 for ( cit = memmgr->
begin(); cit != memmgr->
end(); ++cit ) {
631 interface_header_t *ih = (interface_header_t *)*cit;
632 if (ih->serial == mem_serial) {
633 strncpy(type, ih->type, __INTERFACE_TYPE_SIZE);
634 strncpy(
id, ih->id, __INTERFACE_ID_SIZE);
639 throw BlackBoardNoWritingInstanceException(type,
id);
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.
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.
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
void unlock() const
Unlock list.
Timestamp data, must be present and first entries for each interface data structs! This leans on time...
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.
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.