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();