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,
103 iface->set_instance_serial(next_instance_serial());
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;
178 BlackBoardInterfaceManager::next_instance_serial()
182 return instance_serial++;
184 throw BBNotMasterException(
"Instance serial can only be requested by BB Master");
199 BlackBoardInterfaceManager::create_interface(
const char *type,
200 const char *identifier,
202 Interface *&interface,
205 interface_header_t *ih;
208 interface = new_interface_instance(type, identifier, owner);
210 ptr = memmgr->alloc_nolock(interface->datasize() +
sizeof(interface_header_t));
211 ih = (interface_header_t *)ptr;
212 }
catch (OutOfMemoryException &e) {
214 "BlackBoardInterfaceManager::createInterface: interface of type %s could not be created",
220 memset(ptr, 0, interface->datasize() +
sizeof(interface_header_t));
222 strncpy(ih->type, type, INTERFACE_TYPE_SIZE_ - 1);
223 strncpy(ih->id, identifier, INTERFACE_ID_SIZE_ - 1);
224 memcpy(ih->hash, interface->hash(), INTERFACE_HASH_SIZE_);
227 ih->serial = next_mem_serial();
228 ih->flag_writer_active = 0;
230 rwlocks[ih->serial] =
new RefCountRWLock();
232 interface->set_memory(ih->serial, ptr, (
char *)ptr +
sizeof(interface_header_t));
248 const char *identifier,
251 if (strlen(type) > INTERFACE_TYPE_SIZE_) {
252 throw Exception(
"Interface type '%s' too long, maximum length is %zu",
254 INTERFACE_TYPE_SIZE_);
256 if (strlen(identifier) > INTERFACE_ID_SIZE_) {
257 throw Exception(
"Interface ID '%s' too long, maximum length is %zu", type, INTERFACE_ID_SIZE_);
264 bool created =
false;
268 ptr = find_interface_in_memory(type, identifier);
273 iface = new_interface_instance(type, identifier, owner);
275 if ((iface->
hash_size() != INTERFACE_HASH_SIZE_)
276 || (memcmp(iface->
hash(), ih->
hash, INTERFACE_HASH_SIZE_) != 0)) {
280 rwlocks[ih->
serial]->ref();
283 create_interface(type, identifier, owner, iface, ptr);
287 owner_info_[iface->
uid()].readers.push_back(iface);
288 iface->set_readwrite(
false, rwlocks[ih->
serial]);
302 delete_interface_instance(iface);
324 std::list<Interface *>
326 const char *id_pattern,
332 std::list<Interface *> rv;
339 for (cit = memmgr->
begin(); cit != memmgr->
end(); ++cit) {
344 char type[INTERFACE_TYPE_SIZE_ + 1];
345 char id[INTERFACE_ID_SIZE_ + 1];
346 type[INTERFACE_TYPE_SIZE_] = 0;
347 id[INTERFACE_TYPE_SIZE_] = 0;
348 strncpy(type, ih->
type, INTERFACE_TYPE_SIZE_);
349 strncpy(
id, ih->
id, INTERFACE_ID_SIZE_);
351 if ((fnmatch(type_pattern, type, 0) == FNM_NOMATCH)
352 || (fnmatch(id_pattern,
id, 0) == FNM_NOMATCH)) {
358 iface = new_interface_instance(ih->
type, ih->
id, owner);
361 if ((iface->
hash_size() != INTERFACE_HASH_SIZE_)
362 || (memcmp(iface->
hash(), ih->
hash, INTERFACE_HASH_SIZE_) != 0)) {
366 rwlocks[ih->
serial]->ref();
368 owner_info_[iface->
uid()].readers.push_back(iface);
369 iface->set_readwrite(
false, rwlocks[ih->
serial]);
379 for (std::list<Interface *>::iterator j = rv.begin(); j != rv.end(); ++j) {
385 delete_interface_instance(iface);
386 for (std::list<Interface *>::iterator i = rv.begin(); i != rv.end(); ++i) {
387 delete_interface_instance(*i);
413 const char *identifier,
416 if (strlen(type) > INTERFACE_TYPE_SIZE_) {
417 throw Exception(
"Interface type '%s' too long, maximum length is %zu",
419 INTERFACE_TYPE_SIZE_);
421 if (strlen(identifier) > INTERFACE_ID_SIZE_) {
422 throw Exception(
"Interface ID '%s' too long, maximum length is %zu", type, INTERFACE_ID_SIZE_);
431 bool created =
false;
434 ptr = find_interface_in_memory(type, identifier);
443 iface = new_interface_instance(type, identifier, owner);
444 if ((iface->
hash_size() != INTERFACE_HASH_SIZE_)
445 || (memcmp(iface->
hash(), ih->
hash, INTERFACE_HASH_SIZE_) != 0)) {
449 rwlocks[ih->
serial]->ref();
452 create_interface(type, identifier, owner, iface, ptr);
456 owner_info_[iface->
uid()].writer = iface;
457 iface->set_readwrite(
true, rwlocks[ih->
serial]);
462 writer_interfaces[ih->
serial] = iface;
472 delete_interface_instance(iface);
487 if (interface == NULL)
490 bool destroyed =
false;
494 bool killed_writer = interface->write_access_;
497 if (interface->write_access_) {
498 writer_interfaces.erase(interface->mem_serial_);
500 memmgr->
free(interface->mem_real_ptr_);
503 if (interface->write_access_) {
505 writer_interfaces.erase(interface->mem_serial_);
522 delete_interface_instance(interface);
537 for (cit = memmgr->
begin(); cit != memmgr->
end(); ++cit) {
541 char type[INTERFACE_TYPE_SIZE_ + 1];
542 char id[INTERFACE_ID_SIZE_ + 1];
544 type[INTERFACE_TYPE_SIZE_] = 0;
545 id[INTERFACE_ID_SIZE_] = 0;
546 strncpy(type, ih->
type, INTERFACE_TYPE_SIZE_);
547 strncpy(
id, ih->
id, INTERFACE_ID_SIZE_);
548 std::string uid = std::string(type) +
"::" + id;
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)) {
595 std::string uid = std::string(type) +
"::" + id;
620 BlackBoardInterfaceManager::writer_for_mem_serial(
unsigned int mem_serial)
622 if (writer_interfaces.find(mem_serial) != writer_interfaces.end()) {
623 return writer_interfaces[mem_serial];
625 char type[INTERFACE_TYPE_SIZE_ + 1] =
"Unknown";
626 char id[INTERFACE_ID_SIZE_ + 1] =
"Invalid";
628 type[INTERFACE_TYPE_SIZE_] = 0;
629 id[INTERFACE_ID_SIZE_] = 0;
630 std::string uid =
"Unknown::Invalid";
632 BlackBoardMemoryManager::ChunkIterator cit;
633 for (cit = memmgr->
begin(); cit != memmgr->
end(); ++cit) {
634 interface_header_t *ih = (interface_header_t *)*cit;
635 if (ih->serial == mem_serial) {
636 strncpy(type, ih->type, INTERFACE_TYPE_SIZE_);
637 strncpy(
id, ih->id, INTERFACE_ID_SIZE_);
642 throw BlackBoardNoWritingInstanceException(type,
id);
655 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());
687 if ((info = owner_info_.find(interface->
uid())) != owner_info_.end()) {
688 if (info->second.writer) {
689 rv = info->second.writer->owner();
700 std::list<std::string>
703 std::list<std::string> rv;
706 if ((info = owner_info_.find(uid)) != owner_info_.end()) {
707 std::list<Interface *>::const_iterator i;
708 for (i = info->second.readers.begin(); i != info->second.readers.end(); ++i) {
709 rv.push_back((*i)->owner());
726 if ((info = owner_info_.find(uid)) != owner_info_.end()) {
727 if (info->second.writer) {
728 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 void notify_of_data_change(const Interface *interface)
Notify of data change.
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 ~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.
bool is_master() const
Check if this BB memory manager is the master.
BlackBoard message manager.
void notify_of_reader_added(const Interface *interface, unsigned int event_instance_serial)
Notify that reader has been added.
void notify_of_data_change(const Interface *interface)
Notify of data change.
void notify_of_writer_removed(const Interface *interface, unsigned int event_instance_serial)
Notify that writer has been removed.
void notify_of_writer_added(const Interface *interface, unsigned int event_instance_serial)
Notify that writer has been added.
void notify_of_interface_destroyed(const char *type, const char *id)
Notify that an interface has been destroyed.
void notify_of_interface_created(const char *type, const char *id)
Notify that an interface has been created.
void notify_of_reader_removed(const Interface *interface, unsigned int event_instance_serial)
Notify that reader has been removed.
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.
const char * uid() const
Get unique identifier of interface.
unsigned short serial() const
Get instance serial 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