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/internal/interface_manager.h>
24 
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>
34 
35 #include <interface/interface.h>
36 #include <interface/interface_info.h>
37 
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>
44 
45 #include <cstdlib>
46 #include <cstring>
47 #include <fnmatch.h>
48 
49 namespace fawkes {
50 
51 /** @class BlackBoardInterfaceManager <blackboard/internal/interface_manager.h>
52  * BlackBoard interface manager.
53  * This class is used by the BlackBoard to manage interfaces stored in the
54  * shared memory.
55  *
56  * @author Tim Niemueller
57  */
58 
59 
60 /** Constructor.
61  * The shared memory segment is created with data from bbconfig.h.
62  * @param bb_memmgr BlackBoard memory manager to use
63  * @param bb_msgmgr BlackBoard message manager to use
64  * @param bb_notifier BlackBoard notifier to all for events
65  * @see bbconfig.h
66  */
68  BlackBoardMessageManager *bb_msgmgr,
69  BlackBoardNotifier *bb_notifier)
70 {
71  memmgr = bb_memmgr;
72  msgmgr = bb_msgmgr;
73  notifier = bb_notifier;
74 
75  instance_serial = 1;
76  instance_factory = new BlackBoardInstanceFactory();
77  mutex = new Mutex();
78 
79  writer_interfaces.clear();
80  rwlocks.clear();
81 }
82 
83 
84 /** Destructor */
86 {
87  delete mutex;
88  delete instance_factory;
89 }
90 
91 
92 /** Creates a new interface instance.
93  * This method will look in the libinterfaces shared object for a factory function
94  * for the interface of the given type. If this was found a new instance of the
95  * interface is returned.
96  * @param type type of the interface
97  * @param identifier identifier of the interface
98  * @return a new instance of the requested interface type
99  * @exception BlackBoardInterfaceNotFoundException thrown if the factory function
100  * for the given interface type could not be found
101  */
102 Interface *
103 BlackBoardInterfaceManager::new_interface_instance(const char *type, const char *identifier, const char *owner)
104 {
105  Interface *iface = instance_factory->new_interface_instance(type, identifier);
106 
107  iface->set_instance_serial(next_instance_serial());
108  iface->set_mediators(this, msgmgr);
109  if (owner) iface->set_owner(owner);
110  return iface;
111 }
112 
113 
114 /** Destroy an interface instance.
115  * The destroyer function for the given interface is called to destroy the given
116  * interface instance.
117  * @param interface to destroy
118  * @exception BlackBoardInterfaceNotFoundException thrown if the destroyer function
119  * for the given interface could not be found. The interface will not be freed.
120  */
121 void
122 BlackBoardInterfaceManager::delete_interface_instance(Interface *interface)
123 {
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) {
128  info.writer = NULL;
129  }
130  } else {
131  info.readers.remove(interface);
132  }
133  }
134  instance_factory->delete_interface_instance(interface);
135 }
136 
137 
138 /** search memory chunks if the desired interface has been allocated already.
139  * @param type type of the interface to look for
140  * @param identifier identifier of the interface to look for
141  * @return a pointer to the memory of the interface or NULL if not found
142  */
143 void *
144 BlackBoardInterfaceManager::find_interface_in_memory(const char *type, const char *identifier)
145 {
146  interface_header_t *ih;
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)
152  ) {
153  // found it!
154  return *cit;
155  }
156  }
157 
158  return NULL;
159 }
160 
161 
162 /** Get next mem serial.
163  * @return next unique memory serial
164  */
165 unsigned int
166 BlackBoardInterfaceManager::next_mem_serial()
167 {
168  unsigned int serial = 1;
169  interface_header_t *ih;
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;
175  }
176  }
177 
178  return serial;
179 }
180 
181 
182 /** Get next instance serial.
183  * @return next unique instance serial
184  */
185 unsigned int
186 BlackBoardInterfaceManager::next_instance_serial()
187 {
188  if ( memmgr->is_master() ) {
189  // simple, just increment value and return it
190  return instance_serial++;
191  } else {
192  throw BBNotMasterException("Instance serial can only be requested by BB Master");
193  }
194 }
195 
196 
197 /** Create an interface instance.
198  * This will create a new interface instance. Storage in the shared memory
199  * is allocated to hold the interface data.
200  * @param type type of the interface
201  * @param identifier identifier of the interface
202  * @param interface reference to a pointer where the interface will be created
203  * @param ptr reference to pointer of interface memory
204  * @exception OutOfMemoryException thrown if there is not enough memory in the
205  * BlackBoard to create the interface
206  */
207 void
208 BlackBoardInterfaceManager::create_interface(const char *type, const char *identifier,
209  const char *owner,
210  Interface* &interface, void* &ptr)
211 {
212  interface_header_t *ih;
213 
214  // create new interface and allocate appropriate chunk
215  interface = new_interface_instance(type, identifier, owner);
216  try {
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);
221  memmgr->unlock();
222  mutex->unlock();
223  throw;
224  }
225  memset(ptr, 0, interface->datasize() + sizeof(interface_header_t));
226 
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);
230 
231  ih->refcount = 0;
232  ih->serial = next_mem_serial();
233  ih->flag_writer_active = 0;
234  ih->num_readers = 0;
235  rwlocks[ih->serial] = new RefCountRWLock();
236 
237  interface->set_memory(ih->serial, ptr, (char *)ptr + sizeof(interface_header_t));
238 }
239 
240 
241 /** Open interface for reading.
242  * This will create a new interface instance of the given type. The result can be
243  * casted to the appropriate type.
244  * @param type type of the interface
245  * @param identifier identifier of the interface
246  * @param owner name of entity which opened this interface. If using the BlackBoardAspect
247  * to access the blackboard leave this untouched unless you have a good reason.
248  * @return new fully initialized interface instance of requested type
249  * @exception OutOfMemoryException thrown if there is not enough free space for
250  * the requested interface.
251  */
252 Interface *
253 BlackBoardInterfaceManager::open_for_reading(const char *type, const char *identifier, const char *owner)
254 {
255  if (strlen(type) > __INTERFACE_TYPE_SIZE) {
256  throw Exception("Interface type '%s' too long, maximum length is %zu",
257  type, __INTERFACE_TYPE_SIZE);
258  }
259  if (strlen(identifier) > __INTERFACE_ID_SIZE) {
260  throw Exception("Interface ID '%s' too long, maximum length is %zu",
261  type, __INTERFACE_ID_SIZE);
262  }
263 
264  mutex->lock();
265  Interface *iface = NULL;
266  void *ptr = NULL;
267  interface_header_t *ih;
268  bool created = false;
269 
270  memmgr->lock();
271 
272  ptr = find_interface_in_memory(type, identifier);
273 
274  try {
275  if ( ptr != NULL ) {
276  // found, instantiate new interface for given memory chunk
277  iface = new_interface_instance(type, identifier, owner);
278  ih = (interface_header_t *)ptr;
279  if ( (iface->hash_size() != __INTERFACE_HASH_SIZE ) ||
280  (memcmp(iface->hash(), ih->hash, __INTERFACE_HASH_SIZE) != 0) ) {
282  }
283  iface->set_memory(ih->serial, ptr, (char *)ptr + sizeof(interface_header_t));
284  rwlocks[ih->serial]->ref();
285  } else {
286  created = true;
287  create_interface(type, identifier, owner, iface, ptr);
288  ih = (interface_header_t *)ptr;
289  }
290 
291  owner_info_[iface->uid()].readers.push_back(iface);
292  iface->set_readwrite(false, rwlocks[ih->serial]);
293  ih->refcount++;
294  ih->num_readers++;
295 
296  memmgr->unlock();
297  mutex->unlock();
298 
299  if ( created ) {
300  notifier->notify_of_interface_created(type, identifier);
301  }
302  notifier->notify_of_reader_added(iface, iface->serial());
303 
304  } catch (Exception &e) {
305  if (iface) delete_interface_instance(iface);
306  memmgr->unlock();
307  mutex->unlock();
308  throw;
309  }
310 
311  return iface;
312 }
313 
314 
315 /** Open all interfaces of the given type for reading.
316  * This will create interface instances for all currently registered interfaces of
317  * the given type. The result can be casted to the appropriate type.
318  * @param type_pattern pattern of interface types to open, supports wildcards
319  * similar to filenames (*, ?, []), see "man fnmatch" for all supported.
320  * @param id_pattern pattern of interface IDs to open, supports wildcards similar
321  * to filenames (*, ?, []), see "man fnmatch" for all supported.
322  * @param owner name of entity which opened this interface. If using the BlackBoardAspect
323  * to access the blackboard leave this untouched unless you have a good reason.
324  * @return list of new fully initialized interface instances of requested type. The
325  * is allocated using new and you have to free it using delete after you are done
326  * with it!
327  */
328 std::list<Interface *>
330  const char *id_pattern,
331  const char *owner)
332 {
333  mutex->lock();
334  memmgr->lock();
335 
336  std::list<Interface *> rv;
337 
338  Interface *iface = NULL;
339  interface_header_t *ih;
341 
342  try {
343  for ( cit = memmgr->begin(); cit != memmgr->end(); ++cit ) {
344  iface = NULL;
345  ih = (interface_header_t *)*cit;
346 
347  // ensure 0-termination
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);
354 
355  if ((fnmatch(type_pattern, type, 0) == FNM_NOMATCH) ||
356  (fnmatch(id_pattern, id, 0) == FNM_NOMATCH) ) {
357  // type or ID prefix does not match, go on
358  continue;
359  }
360 
361  void *ptr = *cit;
362  iface = new_interface_instance(ih->type, ih->id, owner);
363  iface->set_memory(ih->serial, ptr, (char *)ptr + sizeof(interface_header_t));
364 
365  if ( (iface->hash_size() != __INTERFACE_HASH_SIZE ) ||
366  (memcmp(iface->hash(), ih->hash, __INTERFACE_HASH_SIZE) != 0) ) {
368  }
369 
370  rwlocks[ih->serial]->ref();
371 
372  owner_info_[iface->uid()].readers.push_back(iface);
373  iface->set_readwrite(false, rwlocks[ih->serial]);
374  ih->refcount++;
375  ih->num_readers++;
376 
377  rv.push_back(iface);
378  }
379 
380  mutex->unlock();
381  memmgr->unlock();
382 
383  for (std::list<Interface *>::iterator j = rv.begin(); j != rv.end(); ++j) {
384  notifier->notify_of_reader_added(*j, (*j)->serial());
385  }
386 
387 
388  } catch (Exception &e) {
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);
392  }
393  memmgr->unlock();
394  mutex->unlock();
395  throw;
396  }
397 
398  return rv;
399 }
400 
401 
402 /** Open interface for writing.
403  * This will create a new interface instance of the given type. The result can be
404  * casted to the appropriate type. This will only succeed if there is not already
405  * a writer for the given interface type/id!
406  * @param type type of the interface
407  * @param identifier identifier of the interface
408  * @param owner name of entity which opened this interface. If using the BlackBoardAspect
409  * to access the blackboard leave this untouched unless you have a good reason.
410  * @return new fully initialized interface instance of requested type
411  * @exception OutOfMemoryException thrown if there is not enough free space for
412  * the requested interface.
413  * @exception BlackBoardWriterActiveException thrown if there is already a writing
414  * instance with the same type/id
415  */
416 Interface *
417 BlackBoardInterfaceManager::open_for_writing(const char *type, const char *identifier, const char *owner)
418 {
419  if (strlen(type) > __INTERFACE_TYPE_SIZE) {
420  throw Exception("Interface type '%s' too long, maximum length is %zu",
421  type, __INTERFACE_TYPE_SIZE);
422  }
423  if (strlen(identifier) > __INTERFACE_ID_SIZE) {
424  throw Exception("Interface ID '%s' too long, maximum length is %zu",
425  type, __INTERFACE_ID_SIZE);
426  }
427 
428  mutex->lock();
429  memmgr->lock();
430 
431  Interface *iface = NULL;
432  void *ptr = NULL;
433  interface_header_t *ih;
434  bool created = false;
435 
436  try {
437  ptr = find_interface_in_memory(type, identifier);
438 
439  if ( ptr != NULL ) {
440  // found, check if there is already a writer
441  //instantiate new interface for given memory chunk
442  ih = (interface_header_t *)ptr;
443  if ( ih->flag_writer_active ) {
444  throw BlackBoardWriterActiveException(identifier, type);
445  }
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) ) {
450  }
451  iface->set_memory(ih->serial, ptr, (char *)ptr + sizeof(interface_header_t));
452  rwlocks[ih->serial]->ref();
453  } else {
454  created = true;
455  create_interface(type, identifier, owner, iface, ptr);
456  ih = (interface_header_t *)ptr;
457  }
458 
459  owner_info_[iface->uid()].writer = iface;
460  iface->set_readwrite(true, rwlocks[ih->serial]);
461  ih->flag_writer_active = 1;
462  ih->refcount++;
463 
464  memmgr->unlock();
465  writer_interfaces[ih->serial] = iface;
466 
467  mutex->unlock();
468 
469  if ( created ) {
470  notifier->notify_of_interface_created(type, identifier);
471  }
472  notifier->notify_of_writer_added(iface, iface->serial());
473  } catch (Exception &e) {
474  if (iface) delete_interface_instance(iface);
475  memmgr->unlock();
476  mutex->unlock();
477  throw;
478  }
479 
480  return iface;
481 }
482 
483 
484 /** Close interface.
485  * @param interface interface to close
486  */
487 void
489 {
490  if ( interface == NULL ) return;
491  mutex->lock();
492  bool destroyed = false;
493 
494  // reduce refcount and free memory if refcount is zero
495  interface_header_t *ih = (interface_header_t *)interface->__mem_real_ptr;
496  bool killed_writer = interface->__write_access;
497  if ( --(ih->refcount) == 0 ) {
498  // redeem from memory
499  if ( interface->__write_access ) {
500  writer_interfaces.erase( interface->__mem_serial );
501  }
502  memmgr->free( interface->__mem_real_ptr );
503  destroyed = true;
504  } else {
505  if ( interface->__write_access ) {
506  ih->flag_writer_active = 0;
507  writer_interfaces.erase( interface->__mem_serial );
508  } else {
509  ih->num_readers--;
510  }
511  }
512 
513  mutex->unlock();
514  if (killed_writer) {
515  notifier->notify_of_writer_removed(interface, interface->serial());
516  } else {
517  notifier->notify_of_reader_removed(interface, interface->serial());
518  }
519  if ( destroyed ) {
520  notifier->notify_of_interface_destroyed(interface->__type, interface->__id);
521  }
522 
523  MutexLocker lock(mutex);
524  delete_interface_instance( interface );
525 }
526 
527 
528 /** Get a list of interfaces.
529  * @return list of currently existing interfaces. List may be outdated on
530  * return since there maybe concurrent actions.
531  */
534 {
535  InterfaceInfoList *infl = new InterfaceInfoList();
536 
537  memmgr->lock();
538  interface_header_t *ih;
540  for ( cit = memmgr->begin(); cit != memmgr->end(); ++cit ) {
541  ih = (interface_header_t *)*cit;
543  (Interface::interface_data_ts_t *)((char *)*cit + sizeof(interface_header_t));
544  char type[__INTERFACE_TYPE_SIZE + 1];
545  char id[__INTERFACE_ID_SIZE + 1];
546  // ensure NULL-termination
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;
552  infl->append(ih->type, ih->id, ih->hash, ih->serial,
554  readers(uid), writer(uid),
555  Time(data_ts->timestamp_sec, data_ts->timestamp_usec));
556  }
557 
558  memmgr->unlock();
559 
560  return infl;
561 }
562 
563 
564 /** Get a constrained list of interfaces.
565  * @param type_pattern tyoe pattern, may contain shell-like wildcards * (any number
566  * of characters) and ? (one character), cf. man fnmatch().
567  * @param id_pattern ID pattern, may contain shell-like wildcards * (any number
568  * of characters) and ? (one character), cf. man fnmatch().
569  * @return list of currently existing interfaces matching the given type and
570  * ID patterns. List may be outdated on return since there maybe concurrent
571  * actions.
572  */
574 BlackBoardInterfaceManager::list(const char *type_pattern,
575  const char *id_pattern) const
576 {
577  InterfaceInfoList *infl = new InterfaceInfoList();
578 
579  memmgr->lock();
580  interface_header_t *ih;
582  for ( cit = memmgr->begin(); cit != memmgr->end(); ++cit ) {
583  ih = (interface_header_t *)*cit;
585  (Interface::interface_data_ts_t *)((char *)*cit + sizeof(interface_header_t));
586  char type[__INTERFACE_TYPE_SIZE + 1];
587  char id[__INTERFACE_ID_SIZE + 1];
588  // ensure NULL-termination
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  {
596  std::string uid = std::string(type) + "::" + id;
597  infl->append(ih->type, ih->id, ih->hash, ih->serial,
599  readers(uid), writer(uid),
600  fawkes::Time(data_ts->timestamp_sec, data_ts->timestamp_usec));
601  }
602  }
603 
604  memmgr->unlock();
605 
606  return infl;
607 }
608 
609 
610 /** Get the writer interface for the given mem serial.
611  * @param mem_serial memory serial to get writer for
612  * @return writer interface for given mem serial, or NULL if non exists
613  * @exception BlackBoardNoWritingInstanceException thrown if no writer
614  * was found for the given interface.
615  */
616 Interface *
617 BlackBoardInterfaceManager::writer_for_mem_serial(unsigned int mem_serial)
618 {
619  if ( writer_interfaces.find(mem_serial) != writer_interfaces.end() ) {
620  return writer_interfaces[mem_serial];
621  } else {
622  char type[__INTERFACE_TYPE_SIZE + 1] = "Unknown";
623  char id[__INTERFACE_ID_SIZE + 1] = "Invalid";
624  // ensure NULL-termination
625  type[__INTERFACE_TYPE_SIZE] = 0;
626  id[__INTERFACE_ID_SIZE] = 0;
627  std::string uid = "Unknown::Invalid";
628  memmgr->lock();
630  for ( cit = memmgr->begin(); cit != memmgr->end(); ++cit ) {
632  if (ih->serial == mem_serial) {
633  strncpy(type, ih->type, __INTERFACE_TYPE_SIZE);
634  strncpy(id, ih->id, __INTERFACE_ID_SIZE);
635  break;
636  }
637  }
638  memmgr->unlock();
639  throw BlackBoardNoWritingInstanceException(type, id);
640  }
641 }
642 
643 
644 void
646 {
647  notifier->notify_of_data_change(interface);
648 }
649 
650 
651 bool
653 {
654  return (writer_interfaces.find(interface->__mem_serial) != writer_interfaces.end());
655 }
656 
657 
658 unsigned int
660 {
661  const interface_header_t *ih = (interface_header_t *)interface->__mem_real_ptr;
662  return ih->num_readers;
663 }
664 
665 std::list<std::string>
667 {
668  std::list<std::string> rv;
669  owner_info_.lock();
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());
675  }
676  }
677  owner_info_.unlock();
678  return rv;
679 }
680 
681 
682 std::string
684 {
685  std::string rv;
686  owner_info_.lock();
688  if ((info = owner_info_.find(interface->uid())) != owner_info_.end()) {
689  if (info->second.writer) {
690  rv = info->second.writer->owner();
691  }
692  }
693  owner_info_.unlock();
694  return rv;
695 }
696 
697 
698 /** Get owners of interfaces who opened for reading.
699  * @param uid UID of interface to query for
700  * @return list of readers for this interface
701  */
702 std::list<std::string>
703 BlackBoardInterfaceManager::readers(const std::string &uid) const
704 {
705  std::list<std::string> rv;
706  owner_info_.lock();
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());
712  }
713  }
714  owner_info_.unlock();
715  return rv;
716 }
717 
718 
719 /** Get writer of interface.
720  * @param uid UID of interface to query for
721  * @return owner name of writing interface instance, or empty string of no writer exists
722  */
723 std::string
724 BlackBoardInterfaceManager::writer(const std::string &uid) const
725 {
726  std::string rv;
727  owner_info_.lock();
729  if ((info = owner_info_.find(uid)) != owner_info_.end()) {
730  if (info->second.writer) {
731  rv = info->second.writer->owner();
732  }
733  }
734  owner_info_.unlock();
735  return rv;
736 }
737 
738 
739 } // end namespace fawkes
void notify_of_reader_added(const Interface *interface, unsigned int event_instance_serial)
Notify that reader has been added.
Definition: notifier.cpp:559
int64_t timestamp_sec
time in seconds since Unix epoch
Definition: interface.h:198
Interface * new_interface_instance(const char *type, const char *identifier)
Creates a new interface instance.
BlackBoard instance factory.
unsigned char hash[__INTERFACE_HASH_SIZE]
interface type version hash
ChunkIterator begin()
Get first element for chunk iteration.
unsigned int datasize() const
Get data size.
Definition: interface.cpp:534
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.
Definition: notifier.cpp:368
void lock() const
Lock list.
Definition: lock_map.h:100
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.
Definition: notifier.cpp:463
Fawkes library namespace.
ChunkIterator end()
Get end of chunk list.
void unlock()
Unlock the mutex.
Definition: mutex.cpp:135
char type[__INTERFACE_TYPE_SIZE]
interface type
uint16_t flag_writer_active
1 if there is a writer, 0 otherwise
Mutex locking helper.
Definition: mutex_locker.h:33
BlackBoard memory manager.
virtual void notify_of_data_change(const Interface *interface)
Notify of data change.
uint16_t num_readers
number of active readers
A class for handling time.
Definition: time.h:91
void notify_of_writer_removed(const Interface *interface, unsigned int event_instance_serial)
Notify that writer has been removed.
Definition: notifier.cpp:501
BlackBoard notifier.
Definition: notifier.h:43
void notify_of_data_change(const Interface *interface)
Notify of data change.
Definition: notifier.cpp:660
Base class for all Fawkes BlackBoard interfaces.
Definition: interface.h:79
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.
Map with a lock.
Definition: lock_map.h:37
Thrown if no writer interface is alive.
Definition: exceptions.h:145
const unsigned char * hash() const
Get interface hash.
Definition: interface.cpp:294
Interface * open_for_writing(const char *interface_type, const char *identifier, const char *owner=NULL)
Open interface for writing.
Interface information list.
This struct is used as header for interfaces in memory chunks.
BlackBoardInterfaceManager(BlackBoardMemoryManager *bb_memmgr, BlackBoardMessageManager *bb_msgmgr, BlackBoardNotifier *bb_notifier)
Constructor.
Base class for exceptions in Fawkes.
Definition: exception.h:36
unsigned short serial() const
Get instance serial of interface.
Definition: interface.cpp:697
uint32_t serial
memory serial
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.
Definition: notifier.cpp:403
int64_t timestamp_usec
additional time microseconds
Definition: interface.h:199
Read/write lock with reference counting.
Definition: refc_rwlock.h:33
void unlock() const
Unlock list.
Definition: lock_map.h:120
Timestamp data, must be present and first entries for each interface data structs! This leans on time...
Definition: interface.h:197
Thrown if BlackBoard is not master and master operation has been requested.
Definition: exceptions.h:66
const char * uid() const
Get unique identifier of interface.
Definition: interface.cpp:687
size_t hash_size() const
Get size of interface hash.
Definition: interface.cpp:419
Thrown if versions do not match.
Definition: exceptions.h:108
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.
bool is_writer() const
Check if this is a writing instance.
Definition: interface.cpp:440
uint32_t refcount
reference count
char id[__INTERFACE_ID_SIZE]
interface identifier
virtual std::list< std::string > readers(const Interface *interface) const
Get owners of interfaces who opened for reading.
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.
Definition: mutex.cpp:89
Thrown if a writer is already active on an interface that writing has been requested for...
Definition: exceptions.h:121
Mutex mutual exclusion lock.
Definition: mutex.h:32
void notify_of_reader_removed(const Interface *interface, unsigned int event_instance_serial)
Notify that reader has been removed.
Definition: notifier.cpp:597
virtual bool exists_writer(const Interface *interface) const
Check if a writer exists for the given interface.
System ran out of memory and desired operation could not be fulfilled.
Definition: system.h:32
void append(const char *format,...)
Append messages to the message list.
Definition: exception.cpp:341