23 #include <blackboard/blackboard.h>
24 #include <blackboard/exceptions.h>
25 #include <blackboard/interface_listener.h>
26 #include <blackboard/interface_observer.h>
27 #include <blackboard/internal/instance_factory.h>
28 #include <blackboard/internal/interface_manager.h>
29 #include <blackboard/internal/interface_mem_header.h>
30 #include <blackboard/internal/memory_manager.h>
31 #include <blackboard/internal/message_manager.h>
32 #include <blackboard/internal/notifier.h>
33 #include <core/exceptions/system.h>
34 #include <core/threading/mutex.h>
35 #include <core/threading/mutex_locker.h>
36 #include <core/threading/refc_rwlock.h>
37 #include <interface/interface.h>
38 #include <interface/interface_info.h>
39 #include <utils/system/dynamic_module/module.h>
40 #include <utils/time/time.h>
69 notifier = bb_notifier;
75 writer_interfaces.clear();
83 delete instance_factory;
97 BlackBoardInterfaceManager::new_interface_instance(
const char *type,
98 const char *identifier,
104 iface->set_mediators(
this, msgmgr);
106 iface->set_owner(owner);
118 BlackBoardInterfaceManager::delete_interface_instance(Interface *interface)
120 if (owner_info_.find(interface->uid()) != owner_info_.end()) {
121 OwnerInfo &info = owner_info_[interface->uid()];
122 if (interface->is_writer()) {
123 if (info.writer == interface) {
127 info.readers.remove(interface);
139 BlackBoardInterfaceManager::find_interface_in_memory(
const char *type,
const char *identifier)
141 interface_header_t * ih;
142 BlackBoardMemoryManager::ChunkIterator cit;
143 for (cit = memmgr->
begin(); cit != memmgr->
end(); ++cit) {
144 ih = (interface_header_t *)*cit;
145 if ((strncmp(ih->type, type, INTERFACE_TYPE_SIZE_) == 0)
146 && (strncmp(ih->id, identifier, INTERFACE_ID_SIZE_) == 0)) {
159 BlackBoardInterfaceManager::next_mem_serial()
161 unsigned int serial = 1;
162 interface_header_t * ih;
163 BlackBoardMemoryManager::ChunkIterator cit;
164 for (cit = memmgr->
begin(); cit != memmgr->
end(); ++cit) {
165 ih = (interface_header_t *)*cit;
166 if (ih->serial >= serial) {
167 serial = ih->serial + 1;
185 BlackBoardInterfaceManager::create_interface(
const char *type,
186 const char *identifier,
188 Interface *&interface,
191 interface_header_t *ih;
194 interface = new_interface_instance(type, identifier, owner);
196 ptr = memmgr->alloc_nolock(interface->datasize() +
sizeof(interface_header_t));
197 ih = (interface_header_t *)ptr;
198 }
catch (OutOfMemoryException &e) {
200 "BlackBoardInterfaceManager::createInterface: interface of type %s could not be created",
206 memset(ptr, 0, interface->datasize() +
sizeof(interface_header_t));
208 strncpy(ih->type, type, INTERFACE_TYPE_SIZE_ - 1);
209 strncpy(ih->id, identifier, INTERFACE_ID_SIZE_ - 1);
210 memcpy(ih->hash, interface->hash(), INTERFACE_HASH_SIZE_);
213 ih->serial = next_mem_serial();
214 ih->flag_writer_active = 0;
216 rwlocks[ih->serial] =
new RefCountRWLock();
218 interface->set_memory(ih->serial, ptr, (
char *)ptr +
sizeof(interface_header_t));
234 const char *identifier,
237 if (strlen(type) > INTERFACE_TYPE_SIZE_) {
238 throw Exception(
"Interface type '%s' too long, maximum length is %zu",
240 INTERFACE_TYPE_SIZE_);
242 if (strlen(identifier) > INTERFACE_ID_SIZE_) {
243 throw Exception(
"Interface ID '%s' too long, maximum length is %zu", type, INTERFACE_ID_SIZE_);
250 bool created =
false;
254 ptr = find_interface_in_memory(type, identifier);
259 iface = new_interface_instance(type, identifier, owner);
261 if ((iface->
hash_size() != INTERFACE_HASH_SIZE_)
262 || (memcmp(iface->
hash(), ih->
hash, INTERFACE_HASH_SIZE_) != 0)) {
266 rwlocks[ih->
serial]->ref();
269 create_interface(type, identifier, owner, iface, ptr);
273 owner_info_[iface->
uid()].readers.push_back(iface);
274 iface->set_readwrite(
false, rwlocks[ih->
serial]);
288 delete_interface_instance(iface);
310 std::list<Interface *>
312 const char *id_pattern,
318 std::list<Interface *> rv;
325 for (cit = memmgr->
begin(); cit != memmgr->
end(); ++cit) {
330 char type[INTERFACE_TYPE_SIZE_ + 1];
331 char id[INTERFACE_ID_SIZE_ + 1];
332 type[INTERFACE_TYPE_SIZE_] = 0;
333 id[INTERFACE_TYPE_SIZE_] = 0;
334 strncpy(type, ih->
type, INTERFACE_TYPE_SIZE_);
335 strncpy(
id, ih->
id, INTERFACE_ID_SIZE_);
337 if ((fnmatch(type_pattern, type, 0) == FNM_NOMATCH)
338 || (fnmatch(id_pattern,
id, 0) == FNM_NOMATCH)) {
344 iface = new_interface_instance(ih->
type, ih->
id, owner);
347 if ((iface->
hash_size() != INTERFACE_HASH_SIZE_)
348 || (memcmp(iface->
hash(), ih->
hash, INTERFACE_HASH_SIZE_) != 0)) {
352 rwlocks[ih->
serial]->ref();
354 owner_info_[iface->
uid()].readers.push_back(iface);
355 iface->set_readwrite(
false, rwlocks[ih->
serial]);
365 for (std::list<Interface *>::iterator j = rv.begin(); j != rv.end(); ++j) {
371 delete_interface_instance(iface);
372 for (std::list<Interface *>::iterator i = rv.begin(); i != rv.end(); ++i) {
373 delete_interface_instance(*i);
399 const char *identifier,
402 if (strlen(type) > INTERFACE_TYPE_SIZE_) {
403 throw Exception(
"Interface type '%s' too long, maximum length is %zu",
405 INTERFACE_TYPE_SIZE_);
407 if (strlen(identifier) > INTERFACE_ID_SIZE_) {
408 throw Exception(
"Interface ID '%s' too long, maximum length is %zu", type, INTERFACE_ID_SIZE_);
417 bool created =
false;
420 ptr = find_interface_in_memory(type, identifier);
429 iface = new_interface_instance(type, identifier, owner);
430 if ((iface->
hash_size() != INTERFACE_HASH_SIZE_)
431 || (memcmp(iface->
hash(), ih->
hash, INTERFACE_HASH_SIZE_) != 0)) {
435 rwlocks[ih->
serial]->ref();
438 create_interface(type, identifier, owner, iface, ptr);
442 owner_info_[iface->
uid()].writer = iface;
443 iface->set_readwrite(
true, rwlocks[ih->
serial]);
448 writer_interfaces[ih->
serial] = iface;
458 delete_interface_instance(iface);
473 if (interface == NULL)
476 bool destroyed =
false;
480 bool killed_writer = interface->write_access_;
483 if (interface->write_access_) {
484 writer_interfaces.erase(interface->mem_serial_);
486 memmgr->
free(interface->mem_real_ptr_);
489 if (interface->write_access_) {
491 writer_interfaces.erase(interface->mem_serial_);
508 delete_interface_instance(interface);
523 for (cit = memmgr->
begin(); cit != memmgr->
end(); ++cit) {
527 char type[INTERFACE_TYPE_SIZE_ + 1];
528 char id[INTERFACE_ID_SIZE_ + 1];
530 type[INTERFACE_TYPE_SIZE_] = 0;
531 id[INTERFACE_ID_SIZE_] = 0;
532 strncpy(type, ih->
type, INTERFACE_TYPE_SIZE_);
533 strncpy(
id, ih->
id, INTERFACE_ID_SIZE_);
534 std::string uid = std::string(type) +
"::" + id;
568 for (cit = memmgr->
begin(); cit != memmgr->
end(); ++cit) {
572 char type[INTERFACE_TYPE_SIZE_ + 1];
573 char id[INTERFACE_ID_SIZE_ + 1];
575 type[INTERFACE_TYPE_SIZE_] = 0;
576 id[INTERFACE_ID_SIZE_] = 0;
577 strncpy(type, ih->
type, INTERFACE_TYPE_SIZE_);
578 strncpy(
id, ih->
id, INTERFACE_ID_SIZE_);
579 if ((fnmatch(type_pattern, type, FNM_NOESCAPE) == 0)
580 && (fnmatch(id_pattern,
id, FNM_NOESCAPE) == 0)) {
581 std::string uid = std::string(type) +
"::" + id;
606 BlackBoardInterfaceManager::writer_for_mem_serial(
unsigned int mem_serial)
608 if (writer_interfaces.find(mem_serial) != writer_interfaces.end()) {
609 return writer_interfaces[mem_serial];
611 char type[INTERFACE_TYPE_SIZE_ + 1] =
"Unknown";
612 char id[INTERFACE_ID_SIZE_ + 1] =
"Invalid";
614 type[INTERFACE_TYPE_SIZE_] = 0;
615 id[INTERFACE_ID_SIZE_] = 0;
616 std::string uid =
"Unknown::Invalid";
618 BlackBoardMemoryManager::ChunkIterator cit;
619 for (cit = memmgr->
begin(); cit != memmgr->
end(); ++cit) {
620 interface_header_t *ih = (interface_header_t *)*cit;
621 if (ih->serial == mem_serial) {
622 strncpy(type, ih->type, INTERFACE_TYPE_SIZE_);
623 strncpy(
id, ih->id, INTERFACE_ID_SIZE_);
628 throw BlackBoardNoWritingInstanceException(type,
id);
641 return (writer_interfaces.find(interface->mem_serial_) != writer_interfaces.end());
651 std::list<std::string>
654 std::list<std::string> rv;
657 if ((info = owner_info_.find(interface->
uid())) != owner_info_.end()) {
658 std::list<Interface *>::const_iterator i;
659 for (i = info->second.readers.begin(); i != info->second.readers.end(); ++i) {
660 rv.push_back((*i)->owner());
673 if ((info = owner_info_.find(interface->
uid())) != owner_info_.end()) {
674 if (info->second.writer) {
675 rv = info->second.writer->owner();
686 std::list<std::string>
689 std::list<std::string> rv;
692 if ((info = owner_info_.find(uid)) != owner_info_.end()) {
693 std::list<Interface *>::const_iterator i;
694 for (i = info->second.readers.begin(); i != info->second.readers.end(); ++i) {
695 rv.push_back((*i)->owner());
712 if ((info = owner_info_.find(uid)) != owner_info_.end()) {
713 if (info->second.writer) {
714 rv = info->second.writer->owner();
BlackBoard instance factory.
void delete_interface_instance(Interface *interface)
Destroy an interface instance.
Interface * new_interface_instance(const char *type, const char *identifier)
Creates a new interface instance.
virtual unsigned int num_readers(const Interface *interface) const
Get number of readers.
virtual std::list< std::string > readers(const Interface *interface) const
Get owners of interfaces who opened for reading.
BlackBoardInterfaceManager(BlackBoardMemoryManager *bb_memmgr, BlackBoardMessageManager *bb_msgmgr, BlackBoardNotifier *bb_notifier)
Constructor.
InterfaceInfoList * list_all() const
Get a list of interfaces.
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.
InterfaceInfoList * list(const char *type_pattern, const char *id_pattern) const
Get a constrained list of interfaces.
virtual bool exists_writer(const Interface *interface) const
Check if a writer exists for the given interface.
Interface * open_for_writing(const char *interface_type, const char *identifier, const char *owner=NULL)
Open interface for writing.
virtual std::string writer(const Interface *interface) const
Get writer of interface.
virtual void notify_of_data_refresh(const Interface *interface, bool has_changed)
Notify of data change.
virtual ~BlackBoardInterfaceManager()
Destructor.
void close(Interface *interface)
Close interface.
Interface * open_for_reading(const char *interface_type, const char *identifier, const char *owner=NULL)
Open interface for reading.
Thrown if versions do not match.
Iterator for memory chunks.
BlackBoard memory manager.
void unlock()
Unlock memory.
void free(void *chunk_ptr)
Free a memory chunk.
ChunkIterator end()
Get end of chunk list.
ChunkIterator begin()
Get first element for chunk iteration.
BlackBoard message manager.
void notify_of_writer_added(const Interface *interface, Uuid event_instance_serial) noexcept
Notify that writer has been added.
void notify_of_writer_removed(const Interface *interface, Uuid event_instance_serial) noexcept
Notify that writer has been removed.
void notify_of_interface_destroyed(const char *type, const char *id) noexcept
Notify that an interface has been destroyed.
void notify_of_reader_added(const Interface *interface, Uuid event_instance_serial) noexcept
Notify that reader has been added.
void notify_of_reader_removed(const Interface *interface, Uuid event_instance_serial) noexcept
Notify that reader has been removed.
void notify_of_data_refresh(const Interface *interface, bool has_changed)
Notify of data change.
void notify_of_interface_created(const char *type, const char *id) noexcept
Notify that an interface has been created.
Thrown if a writer is already active on an interface that writing has been requested for.
Base class for exceptions in Fawkes.
Interface information list.
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.
Base class for all Fawkes BlackBoard interfaces.
size_t hash_size() const
Get size of interface hash.
const unsigned char * hash() const
Get interface hash.
Uuid serial() const
Get instance serial of interface.
const char * uid() const
Get unique identifier of interface.
void lock() const
Lock list.
void unlock() const
Unlock list.
Mutex mutual exclusion lock.
void lock()
Lock this mutex.
void unlock()
Unlock the mutex.
A class for handling time.
Fawkes library namespace.
Timestamp data, must be present and first entries for each interface data structs!...
int64_t timestamp_usec
additional time microseconds
int64_t timestamp_sec
time in seconds since Unix epoch