Fawkes API Fawkes Development Version
interface_manager.cpp
1
2/***************************************************************************
3 * interface_manager.cpp - BlackBoard interface manager
4 *
5 * Created: Mon Oct 09 19:08:29 2006
6 * Copyright 2006-2015 Tim Niemueller [www.niemueller.de]
7 ****************************************************************************/
8
9/* This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version. A runtime exception applies to
13 * this software (see LICENSE.GPL_WRE file mentioned below for details).
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU Library General Public License for more details.
19 *
20 * Read the full text in the LICENSE.GPL_WRE file in the doc directory.
21 */
22
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>
41
42#include <cstdlib>
43#include <cstring>
44#include <fnmatch.h>
45
46namespace fawkes {
47
48/** @class BlackBoardInterfaceManager <blackboard/internal/interface_manager.h>
49 * BlackBoard interface manager.
50 * This class is used by the BlackBoard to manage interfaces stored in the
51 * shared memory.
52 *
53 * @author Tim Niemueller
54 */
55
56/** Constructor.
57 * The shared memory segment is created with data from bbconfig.h.
58 * @param bb_memmgr BlackBoard memory manager to use
59 * @param bb_msgmgr BlackBoard message manager to use
60 * @param bb_notifier BlackBoard notifier to all for events
61 * @see bbconfig.h
62 */
64 BlackBoardMessageManager *bb_msgmgr,
65 BlackBoardNotifier * bb_notifier)
66{
67 memmgr = bb_memmgr;
68 msgmgr = bb_msgmgr;
69 notifier = bb_notifier;
70
71 instance_serial = 1;
72 instance_factory = new BlackBoardInstanceFactory();
73 mutex = new Mutex();
74
75 writer_interfaces.clear();
76 rwlocks.clear();
77}
78
79/** Destructor */
81{
82 delete mutex;
83 delete instance_factory;
84}
85
86/** Creates a new interface instance.
87 * This method will look in the libinterfaces shared object for a factory function
88 * for the interface of the given type. If this was found a new instance of the
89 * interface is returned.
90 * @param type type of the interface
91 * @param identifier identifier of the interface
92 * @return a new instance of the requested interface type
93 * @exception BlackBoardInterfaceNotFoundException thrown if the factory function
94 * for the given interface type could not be found
95 */
97BlackBoardInterfaceManager::new_interface_instance(const char *type,
98 const char *identifier,
99 const char *owner)
100{
101 Interface *iface = instance_factory->new_interface_instance(type, identifier);
102
103 //iface->set_instance_serial(next_instance_serial());
104 iface->set_mediators(this, msgmgr);
105 if (owner)
106 iface->set_owner(owner);
107 return iface;
108}
109
110/** Destroy an interface instance.
111 * The destroyer function for the given interface is called to destroy the given
112 * interface instance.
113 * @param interface to destroy
114 * @exception BlackBoardInterfaceNotFoundException thrown if the destroyer function
115 * for the given interface could not be found. The interface will not be freed.
116 */
117void
118BlackBoardInterfaceManager::delete_interface_instance(Interface *interface)
119{
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) {
124 info.writer = NULL;
125 }
126 } else {
127 info.readers.remove(interface);
128 }
129 }
130 instance_factory->delete_interface_instance(interface);
131}
132
133/** search memory chunks if the desired interface has been allocated already.
134 * @param type type of the interface to look for
135 * @param identifier identifier of the interface to look for
136 * @return a pointer to the memory of the interface or NULL if not found
137 */
138void *
139BlackBoardInterfaceManager::find_interface_in_memory(const char *type, const char *identifier)
140{
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)) {
147 // found it!
148 return *cit;
149 }
150 }
151
152 return NULL;
153}
154
155/** Get next mem serial.
156 * @return next unique memory serial
157 */
158unsigned int
159BlackBoardInterfaceManager::next_mem_serial()
160{
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;
168 }
169 }
170
171 return serial;
172}
173
174/** Create an interface instance.
175 * This will create a new interface instance. Storage in the shared memory
176 * is allocated to hold the interface data.
177 * @param type type of the interface
178 * @param identifier identifier of the interface
179 * @param interface reference to a pointer where the interface will be created
180 * @param ptr reference to pointer of interface memory
181 * @exception OutOfMemoryException thrown if there is not enough memory in the
182 * BlackBoard to create the interface
183 */
184void
185BlackBoardInterfaceManager::create_interface(const char *type,
186 const char *identifier,
187 const char *owner,
188 Interface *&interface,
189 void *& ptr)
190{
191 interface_header_t *ih;
192
193 // create new interface and allocate appropriate chunk
194 interface = new_interface_instance(type, identifier, owner);
195 try {
196 ptr = memmgr->alloc_nolock(interface->datasize() + sizeof(interface_header_t));
197 ih = (interface_header_t *)ptr;
198 } catch (OutOfMemoryException &e) {
199 e.append(
200 "BlackBoardInterfaceManager::createInterface: interface of type %s could not be created",
201 type);
202 memmgr->unlock();
203 mutex->unlock();
204 throw;
205 }
206 memset(ptr, 0, interface->datasize() + sizeof(interface_header_t));
207
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_);
211
212 ih->refcount = 0;
213 ih->serial = next_mem_serial();
214 ih->flag_writer_active = 0;
215 ih->num_readers = 0;
216 rwlocks[ih->serial] = new RefCountRWLock();
217
218 interface->set_memory(ih->serial, ptr, (char *)ptr + sizeof(interface_header_t));
219}
220
221/** Open interface for reading.
222 * This will create a new interface instance of the given type. The result can be
223 * casted to the appropriate type.
224 * @param type type of the interface
225 * @param identifier identifier of the interface
226 * @param owner name of entity which opened this interface. If using the BlackBoardAspect
227 * to access the blackboard leave this untouched unless you have a good reason.
228 * @return new fully initialized interface instance of requested type
229 * @exception OutOfMemoryException thrown if there is not enough free space for
230 * the requested interface.
231 */
232Interface *
234 const char *identifier,
235 const char *owner)
236{
237 if (strlen(type) > INTERFACE_TYPE_SIZE_) {
238 throw Exception("Interface type '%s' too long, maximum length is %zu",
239 type,
240 INTERFACE_TYPE_SIZE_);
241 }
242 if (strlen(identifier) > INTERFACE_ID_SIZE_) {
243 throw Exception("Interface ID '%s' too long, maximum length is %zu", type, INTERFACE_ID_SIZE_);
244 }
245
246 mutex->lock();
247 Interface * iface = NULL;
248 void * ptr = NULL;
250 bool created = false;
251
252 memmgr->lock();
253
254 ptr = find_interface_in_memory(type, identifier);
255
256 try {
257 if (ptr != NULL) {
258 // found, instantiate new interface for given memory chunk
259 iface = new_interface_instance(type, identifier, owner);
260 ih = (interface_header_t *)ptr;
261 if ((iface->hash_size() != INTERFACE_HASH_SIZE_)
262 || (memcmp(iface->hash(), ih->hash, INTERFACE_HASH_SIZE_) != 0)) {
264 }
265 iface->set_memory(ih->serial, ptr, (char *)ptr + sizeof(interface_header_t));
266 rwlocks[ih->serial]->ref();
267 } else {
268 created = true;
269 create_interface(type, identifier, owner, iface, ptr);
270 ih = (interface_header_t *)ptr;
271 }
272
273 owner_info_[iface->uid()].readers.push_back(iface);
274 iface->set_readwrite(false, rwlocks[ih->serial]);
275 ih->refcount++;
276 ih->num_readers++;
277
278 memmgr->unlock();
279 mutex->unlock();
280
281 if (created) {
282 notifier->notify_of_interface_created(type, identifier);
283 }
284 notifier->notify_of_reader_added(iface, iface->serial());
285
286 } catch (Exception &e) {
287 if (iface)
288 delete_interface_instance(iface);
289 memmgr->unlock();
290 mutex->unlock();
291 throw;
292 }
293
294 return iface;
295}
296
297/** Open all interfaces of the given type for reading.
298 * This will create interface instances for all currently registered interfaces of
299 * the given type. The result can be casted to the appropriate type.
300 * @param type_pattern pattern of interface types to open, supports wildcards
301 * similar to filenames (*, ?, []), see "man fnmatch" for all supported.
302 * @param id_pattern pattern of interface IDs to open, supports wildcards similar
303 * to filenames (*, ?, []), see "man fnmatch" for all supported.
304 * @param owner name of entity which opened this interface. If using the BlackBoardAspect
305 * to access the blackboard leave this untouched unless you have a good reason.
306 * @return list of new fully initialized interface instances of requested type. The
307 * is allocated using new and you have to free it using delete after you are done
308 * with it!
309 */
310std::list<Interface *>
312 const char *id_pattern,
313 const char *owner)
314{
315 mutex->lock();
316 memmgr->lock();
317
318 std::list<Interface *> rv;
319
320 Interface * iface = NULL;
323
324 try {
325 for (cit = memmgr->begin(); cit != memmgr->end(); ++cit) {
326 iface = NULL;
327 ih = (interface_header_t *)*cit;
328
329 // ensure 0-termination
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_);
336
337 if ((fnmatch(type_pattern, type, 0) == FNM_NOMATCH)
338 || (fnmatch(id_pattern, id, 0) == FNM_NOMATCH)) {
339 // type or ID prefix does not match, go on
340 continue;
341 }
342
343 void *ptr = *cit;
344 iface = new_interface_instance(ih->type, ih->id, owner);
345 iface->set_memory(ih->serial, ptr, (char *)ptr + sizeof(interface_header_t));
346
347 if ((iface->hash_size() != INTERFACE_HASH_SIZE_)
348 || (memcmp(iface->hash(), ih->hash, INTERFACE_HASH_SIZE_) != 0)) {
350 }
351
352 rwlocks[ih->serial]->ref();
353
354 owner_info_[iface->uid()].readers.push_back(iface);
355 iface->set_readwrite(false, rwlocks[ih->serial]);
356 ih->refcount++;
357 ih->num_readers++;
358
359 rv.push_back(iface);
360 }
361
362 mutex->unlock();
363 memmgr->unlock();
364
365 for (std::list<Interface *>::iterator j = rv.begin(); j != rv.end(); ++j) {
366 notifier->notify_of_reader_added(*j, (*j)->serial());
367 }
368
369 } catch (Exception &e) {
370 if (iface)
371 delete_interface_instance(iface);
372 for (std::list<Interface *>::iterator i = rv.begin(); i != rv.end(); ++i) {
373 delete_interface_instance(*i);
374 }
375 memmgr->unlock();
376 mutex->unlock();
377 throw;
378 }
379
380 return rv;
381}
382
383/** Open interface for writing.
384 * This will create a new interface instance of the given type. The result can be
385 * casted to the appropriate type. This will only succeed if there is not already
386 * a writer for the given interface type/id!
387 * @param type type of the interface
388 * @param identifier identifier of the interface
389 * @param owner name of entity which opened this interface. If using the BlackBoardAspect
390 * to access the blackboard leave this untouched unless you have a good reason.
391 * @return new fully initialized interface instance of requested type
392 * @exception OutOfMemoryException thrown if there is not enough free space for
393 * the requested interface.
394 * @exception BlackBoardWriterActiveException thrown if there is already a writing
395 * instance with the same type/id
396 */
397Interface *
399 const char *identifier,
400 const char *owner)
401{
402 if (strlen(type) > INTERFACE_TYPE_SIZE_) {
403 throw Exception("Interface type '%s' too long, maximum length is %zu",
404 type,
405 INTERFACE_TYPE_SIZE_);
406 }
407 if (strlen(identifier) > INTERFACE_ID_SIZE_) {
408 throw Exception("Interface ID '%s' too long, maximum length is %zu", type, INTERFACE_ID_SIZE_);
409 }
410
411 mutex->lock();
412 memmgr->lock();
413
414 Interface * iface = NULL;
415 void * ptr = NULL;
417 bool created = false;
418
419 try {
420 ptr = find_interface_in_memory(type, identifier);
421
422 if (ptr != NULL) {
423 // found, check if there is already a writer
424 //instantiate new interface for given memory chunk
425 ih = (interface_header_t *)ptr;
426 if (ih->flag_writer_active) {
427 throw BlackBoardWriterActiveException(identifier, type);
428 }
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)) {
433 }
434 iface->set_memory(ih->serial, ptr, (char *)ptr + sizeof(interface_header_t));
435 rwlocks[ih->serial]->ref();
436 } else {
437 created = true;
438 create_interface(type, identifier, owner, iface, ptr);
439 ih = (interface_header_t *)ptr;
440 }
441
442 owner_info_[iface->uid()].writer = iface;
443 iface->set_readwrite(true, rwlocks[ih->serial]);
444 ih->flag_writer_active = 1;
445 ih->refcount++;
446
447 memmgr->unlock();
448 writer_interfaces[ih->serial] = iface;
449
450 mutex->unlock();
451
452 if (created) {
453 notifier->notify_of_interface_created(type, identifier);
454 }
455 notifier->notify_of_writer_added(iface, iface->serial());
456 } catch (Exception &e) {
457 if (iface)
458 delete_interface_instance(iface);
459 memmgr->unlock();
460 mutex->unlock();
461 throw;
462 }
463
464 return iface;
465}
466
467/** Close interface.
468 * @param interface interface to close
469 */
470void
472{
473 if (interface == NULL)
474 return;
475 mutex->lock();
476 bool destroyed = false;
477
478 // reduce refcount and free memory if refcount is zero
479 interface_header_t *ih = (interface_header_t *)interface->mem_real_ptr_;
480 bool killed_writer = interface->write_access_;
481 if (--(ih->refcount) == 0) {
482 // redeem from memory
483 if (interface->write_access_) {
484 writer_interfaces.erase(interface->mem_serial_);
485 }
486 memmgr->free(interface->mem_real_ptr_);
487 destroyed = true;
488 } else {
489 if (interface->write_access_) {
490 ih->flag_writer_active = 0;
491 writer_interfaces.erase(interface->mem_serial_);
492 } else {
493 ih->num_readers--;
494 }
495 }
496
497 mutex->unlock();
498 if (killed_writer) {
499 notifier->notify_of_writer_removed(interface, interface->serial());
500 } else {
501 notifier->notify_of_reader_removed(interface, interface->serial());
502 }
503 if (destroyed) {
504 notifier->notify_of_interface_destroyed(interface->type_, interface->id_);
505 }
506
507 MutexLocker lock(mutex);
508 delete_interface_instance(interface);
509}
510
511/** Get a list of interfaces.
512 * @return list of currently existing interfaces. List may be outdated on
513 * return since there maybe concurrent actions.
514 */
517{
519
520 memmgr->lock();
523 for (cit = memmgr->begin(); cit != memmgr->end(); ++cit) {
524 ih = (interface_header_t *)*cit;
526 (Interface::interface_data_ts_t *)((char *)*cit + sizeof(interface_header_t));
527 char type[INTERFACE_TYPE_SIZE_ + 1];
528 char id[INTERFACE_ID_SIZE_ + 1];
529 // ensure NULL-termination
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;
535 infl->append(ih->type,
536 ih->id,
537 ih->hash,
538 ih->serial,
540 ih->num_readers,
541 readers(uid),
542 writer(uid),
543 Time(data_ts->timestamp_sec, data_ts->timestamp_usec));
544 }
545
546 memmgr->unlock();
547
548 return infl;
549}
550
551/** Get a constrained list of interfaces.
552 * @param type_pattern tyoe pattern, may contain shell-like wildcards * (any number
553 * of characters) and ? (one character), cf. man fnmatch().
554 * @param id_pattern ID pattern, may contain shell-like wildcards * (any number
555 * of characters) and ? (one character), cf. man fnmatch().
556 * @return list of currently existing interfaces matching the given type and
557 * ID patterns. List may be outdated on return since there maybe concurrent
558 * actions.
559 */
561BlackBoardInterfaceManager::list(const char *type_pattern, const char *id_pattern) const
562{
564
565 memmgr->lock();
568 for (cit = memmgr->begin(); cit != memmgr->end(); ++cit) {
569 ih = (interface_header_t *)*cit;
571 (Interface::interface_data_ts_t *)((char *)*cit + sizeof(interface_header_t));
572 char type[INTERFACE_TYPE_SIZE_ + 1];
573 char id[INTERFACE_ID_SIZE_ + 1];
574 // ensure NULL-termination
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;
582 infl->append(ih->type,
583 ih->id,
584 ih->hash,
585 ih->serial,
587 ih->num_readers,
588 readers(uid),
589 writer(uid),
590 fawkes::Time(data_ts->timestamp_sec, data_ts->timestamp_usec));
591 }
592 }
593
594 memmgr->unlock();
595
596 return infl;
597}
598
599/** Get the writer interface for the given mem serial.
600 * @param mem_serial memory serial to get writer for
601 * @return writer interface for given mem serial, or NULL if non exists
602 * @exception BlackBoardNoWritingInstanceException thrown if no writer
603 * was found for the given interface.
604 */
605Interface *
606BlackBoardInterfaceManager::writer_for_mem_serial(unsigned int mem_serial)
607{
608 if (writer_interfaces.find(mem_serial) != writer_interfaces.end()) {
609 return writer_interfaces[mem_serial];
610 } else {
611 char type[INTERFACE_TYPE_SIZE_ + 1] = "Unknown";
612 char id[INTERFACE_ID_SIZE_ + 1] = "Invalid";
613 // ensure NULL-termination
614 type[INTERFACE_TYPE_SIZE_] = 0;
615 id[INTERFACE_ID_SIZE_] = 0;
616 std::string uid = "Unknown::Invalid";
617 memmgr->lock();
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_);
624 break;
625 }
626 }
627 memmgr->unlock();
628 throw BlackBoardNoWritingInstanceException(type, id);
629 }
630}
631
632void
634{
635 notifier->notify_of_data_refresh(interface, has_changed);
636}
637
638bool
640{
641 return (writer_interfaces.find(interface->mem_serial_) != writer_interfaces.end());
642}
643
644unsigned int
646{
647 const interface_header_t *ih = (interface_header_t *)interface->mem_real_ptr_;
648 return ih->num_readers;
649}
650
651std::list<std::string>
653{
654 std::list<std::string> rv;
655 owner_info_.lock();
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());
661 }
662 }
663 owner_info_.unlock();
664 return rv;
665}
666
667std::string
669{
670 std::string rv;
671 owner_info_.lock();
673 if ((info = owner_info_.find(interface->uid())) != owner_info_.end()) {
674 if (info->second.writer) {
675 rv = info->second.writer->owner();
676 }
677 }
678 owner_info_.unlock();
679 return rv;
680}
681
682/** Get owners of interfaces who opened for reading.
683 * @param uid UID of interface to query for
684 * @return list of readers for this interface
685 */
686std::list<std::string>
687BlackBoardInterfaceManager::readers(const std::string &uid) const
688{
689 std::list<std::string> rv;
690 owner_info_.lock();
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());
696 }
697 }
698 owner_info_.unlock();
699 return rv;
700}
701
702/** Get writer of interface.
703 * @param uid UID of interface to query for
704 * @return owner name of writing interface instance, or empty string of no writer exists
705 */
706std::string
707BlackBoardInterfaceManager::writer(const std::string &uid) const
708{
709 std::string rv;
710 owner_info_.lock();
712 if ((info = owner_info_.find(uid)) != owner_info_.end()) {
713 if (info->second.writer) {
714 rv = info->second.writer->owner();
715 }
716 }
717 owner_info_.unlock();
718 return rv;
719}
720
721} // end namespace fawkes
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.
BlackBoard memory manager.
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.
BlackBoard notifier.
Definition: notifier.h:44
void notify_of_writer_added(const Interface *interface, Uuid event_instance_serial) noexcept
Notify that writer has been added.
Definition: notifier.cpp:495
void notify_of_writer_removed(const Interface *interface, Uuid event_instance_serial) noexcept
Notify that writer has been removed.
Definition: notifier.cpp:532
void notify_of_interface_destroyed(const char *type, const char *id) noexcept
Notify that an interface has been destroyed.
Definition: notifier.cpp:436
void notify_of_reader_added(const Interface *interface, Uuid event_instance_serial) noexcept
Notify that reader has been added.
Definition: notifier.cpp:589
void notify_of_reader_removed(const Interface *interface, Uuid event_instance_serial) noexcept
Notify that reader has been removed.
Definition: notifier.cpp:626
void notify_of_data_refresh(const Interface *interface, bool has_changed)
Notify of data change.
Definition: notifier.cpp:689
void notify_of_interface_created(const char *type, const char *id) noexcept
Notify that an interface has been created.
Definition: notifier.cpp:401
Thrown if a writer is already active on an interface that writing has been requested for.
Definition: exceptions.h:125
Base class for exceptions in Fawkes.
Definition: exception.h:36
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 &timestamp)
Append an interface info.
Base class for all Fawkes BlackBoard interfaces.
Definition: interface.h:80
size_t hash_size() const
Get size of interface hash.
Definition: interface.cpp:426
const unsigned char * hash() const
Get interface hash.
Definition: interface.cpp:305
Uuid serial() const
Get instance serial of interface.
Definition: interface.cpp:695
const char * uid() const
Get unique identifier of interface.
Definition: interface.cpp:686
Map with a lock.
Definition: lock_map.h:36
void lock() const
Lock list.
Definition: lock_map.h:91
void unlock() const
Unlock list.
Definition: lock_map.h:109
Mutex locking helper.
Definition: mutex_locker.h:34
Mutex mutual exclusion lock.
Definition: mutex.h:33
void lock()
Lock this mutex.
Definition: mutex.cpp:87
void unlock()
Unlock the mutex.
Definition: mutex.cpp:131
A class for handling time.
Definition: time.h:93
Fawkes library namespace.
Timestamp data, must be present and first entries for each interface data structs!...
Definition: interface.h:201
int64_t timestamp_usec
additional time microseconds
Definition: interface.h:203
int64_t timestamp_sec
time in seconds since Unix epoch
Definition: interface.h:202
This struct is used as header for interfaces in memory chunks.
char type[INTERFACE_TYPE_SIZE_]
interface type
uint32_t refcount
reference count
uint16_t num_readers
number of active readers
uint16_t flag_writer_active
1 if there is a writer, 0 otherwise
unsigned char hash[INTERFACE_HASH_SIZE_]
interface type version hash
char id[INTERFACE_ID_SIZE_]
interface identifier
uint32_t serial
memory serial