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 
46 namespace 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  */
96 Interface *
97 BlackBoardInterfaceManager::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  */
117 void
118 BlackBoardInterfaceManager::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  */
138 void *
139 BlackBoardInterfaceManager::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  */
158 unsigned int
159 BlackBoardInterfaceManager::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 /** Get next instance serial.
175  * @return next unique instance serial
176  */
177 unsigned int
178 BlackBoardInterfaceManager::next_instance_serial()
179 {
180  if (memmgr->is_master()) {
181  // simple, just increment value and return it
182  return instance_serial++;
183  } else {
184  throw BBNotMasterException("Instance serial can only be requested by BB Master");
185  }
186 }
187 
188 /** Create an interface instance.
189  * This will create a new interface instance. Storage in the shared memory
190  * is allocated to hold the interface data.
191  * @param type type of the interface
192  * @param identifier identifier of the interface
193  * @param interface reference to a pointer where the interface will be created
194  * @param ptr reference to pointer of interface memory
195  * @exception OutOfMemoryException thrown if there is not enough memory in the
196  * BlackBoard to create the interface
197  */
198 void
199 BlackBoardInterfaceManager::create_interface(const char *type,
200  const char *identifier,
201  const char *owner,
202  Interface *&interface,
203  void *& ptr)
204 {
205  interface_header_t *ih;
206 
207  // create new interface and allocate appropriate chunk
208  interface = new_interface_instance(type, identifier, owner);
209  try {
210  ptr = memmgr->alloc_nolock(interface->datasize() + sizeof(interface_header_t));
211  ih = (interface_header_t *)ptr;
212  } catch (OutOfMemoryException &e) {
213  e.append(
214  "BlackBoardInterfaceManager::createInterface: interface of type %s could not be created",
215  type);
216  memmgr->unlock();
217  mutex->unlock();
218  throw;
219  }
220  memset(ptr, 0, interface->datasize() + sizeof(interface_header_t));
221 
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_);
225 
226  ih->refcount = 0;
227  ih->serial = next_mem_serial();
228  ih->flag_writer_active = 0;
229  ih->num_readers = 0;
230  rwlocks[ih->serial] = new RefCountRWLock();
231 
232  interface->set_memory(ih->serial, ptr, (char *)ptr + sizeof(interface_header_t));
233 }
234 
235 /** Open interface for reading.
236  * This will create a new interface instance of the given type. The result can be
237  * casted to the appropriate type.
238  * @param type type of the interface
239  * @param identifier identifier of the interface
240  * @param owner name of entity which opened this interface. If using the BlackBoardAspect
241  * to access the blackboard leave this untouched unless you have a good reason.
242  * @return new fully initialized interface instance of requested type
243  * @exception OutOfMemoryException thrown if there is not enough free space for
244  * the requested interface.
245  */
246 Interface *
248  const char *identifier,
249  const char *owner)
250 {
251  if (strlen(type) > INTERFACE_TYPE_SIZE_) {
252  throw Exception("Interface type '%s' too long, maximum length is %zu",
253  type,
254  INTERFACE_TYPE_SIZE_);
255  }
256  if (strlen(identifier) > INTERFACE_ID_SIZE_) {
257  throw Exception("Interface ID '%s' too long, maximum length is %zu", type, INTERFACE_ID_SIZE_);
258  }
259 
260  mutex->lock();
261  Interface * iface = NULL;
262  void * ptr = NULL;
263  interface_header_t *ih;
264  bool created = false;
265 
266  memmgr->lock();
267 
268  ptr = find_interface_in_memory(type, identifier);
269 
270  try {
271  if (ptr != NULL) {
272  // found, instantiate new interface for given memory chunk
273  iface = new_interface_instance(type, identifier, owner);
274  ih = (interface_header_t *)ptr;
275  if ((iface->hash_size() != INTERFACE_HASH_SIZE_)
276  || (memcmp(iface->hash(), ih->hash, INTERFACE_HASH_SIZE_) != 0)) {
278  }
279  iface->set_memory(ih->serial, ptr, (char *)ptr + sizeof(interface_header_t));
280  rwlocks[ih->serial]->ref();
281  } else {
282  created = true;
283  create_interface(type, identifier, owner, iface, ptr);
284  ih = (interface_header_t *)ptr;
285  }
286 
287  owner_info_[iface->uid()].readers.push_back(iface);
288  iface->set_readwrite(false, rwlocks[ih->serial]);
289  ih->refcount++;
290  ih->num_readers++;
291 
292  memmgr->unlock();
293  mutex->unlock();
294 
295  if (created) {
296  notifier->notify_of_interface_created(type, identifier);
297  }
298  notifier->notify_of_reader_added(iface, iface->serial());
299 
300  } catch (Exception &e) {
301  if (iface)
302  delete_interface_instance(iface);
303  memmgr->unlock();
304  mutex->unlock();
305  throw;
306  }
307 
308  return iface;
309 }
310 
311 /** Open all interfaces of the given type for reading.
312  * This will create interface instances for all currently registered interfaces of
313  * the given type. The result can be casted to the appropriate type.
314  * @param type_pattern pattern of interface types to open, supports wildcards
315  * similar to filenames (*, ?, []), see "man fnmatch" for all supported.
316  * @param id_pattern pattern of interface IDs to open, supports wildcards similar
317  * to filenames (*, ?, []), see "man fnmatch" for all supported.
318  * @param owner name of entity which opened this interface. If using the BlackBoardAspect
319  * to access the blackboard leave this untouched unless you have a good reason.
320  * @return list of new fully initialized interface instances of requested type. The
321  * is allocated using new and you have to free it using delete after you are done
322  * with it!
323  */
324 std::list<Interface *>
326  const char *id_pattern,
327  const char *owner)
328 {
329  mutex->lock();
330  memmgr->lock();
331 
332  std::list<Interface *> rv;
333 
334  Interface * iface = NULL;
335  interface_header_t * ih;
337 
338  try {
339  for (cit = memmgr->begin(); cit != memmgr->end(); ++cit) {
340  iface = NULL;
341  ih = (interface_header_t *)*cit;
342 
343  // ensure 0-termination
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_);
350 
351  if ((fnmatch(type_pattern, type, 0) == FNM_NOMATCH)
352  || (fnmatch(id_pattern, id, 0) == FNM_NOMATCH)) {
353  // type or ID prefix does not match, go on
354  continue;
355  }
356 
357  void *ptr = *cit;
358  iface = new_interface_instance(ih->type, ih->id, owner);
359  iface->set_memory(ih->serial, ptr, (char *)ptr + sizeof(interface_header_t));
360 
361  if ((iface->hash_size() != INTERFACE_HASH_SIZE_)
362  || (memcmp(iface->hash(), ih->hash, INTERFACE_HASH_SIZE_) != 0)) {
364  }
365 
366  rwlocks[ih->serial]->ref();
367 
368  owner_info_[iface->uid()].readers.push_back(iface);
369  iface->set_readwrite(false, rwlocks[ih->serial]);
370  ih->refcount++;
371  ih->num_readers++;
372 
373  rv.push_back(iface);
374  }
375 
376  mutex->unlock();
377  memmgr->unlock();
378 
379  for (std::list<Interface *>::iterator j = rv.begin(); j != rv.end(); ++j) {
380  notifier->notify_of_reader_added(*j, (*j)->serial());
381  }
382 
383  } catch (Exception &e) {
384  if (iface)
385  delete_interface_instance(iface);
386  for (std::list<Interface *>::iterator i = rv.begin(); i != rv.end(); ++i) {
387  delete_interface_instance(*i);
388  }
389  memmgr->unlock();
390  mutex->unlock();
391  throw;
392  }
393 
394  return rv;
395 }
396 
397 /** Open interface for writing.
398  * This will create a new interface instance of the given type. The result can be
399  * casted to the appropriate type. This will only succeed if there is not already
400  * a writer for the given interface type/id!
401  * @param type type of the interface
402  * @param identifier identifier of the interface
403  * @param owner name of entity which opened this interface. If using the BlackBoardAspect
404  * to access the blackboard leave this untouched unless you have a good reason.
405  * @return new fully initialized interface instance of requested type
406  * @exception OutOfMemoryException thrown if there is not enough free space for
407  * the requested interface.
408  * @exception BlackBoardWriterActiveException thrown if there is already a writing
409  * instance with the same type/id
410  */
411 Interface *
413  const char *identifier,
414  const char *owner)
415 {
416  if (strlen(type) > INTERFACE_TYPE_SIZE_) {
417  throw Exception("Interface type '%s' too long, maximum length is %zu",
418  type,
419  INTERFACE_TYPE_SIZE_);
420  }
421  if (strlen(identifier) > INTERFACE_ID_SIZE_) {
422  throw Exception("Interface ID '%s' too long, maximum length is %zu", type, INTERFACE_ID_SIZE_);
423  }
424 
425  mutex->lock();
426  memmgr->lock();
427 
428  Interface * iface = NULL;
429  void * ptr = NULL;
430  interface_header_t *ih;
431  bool created = false;
432 
433  try {
434  ptr = find_interface_in_memory(type, identifier);
435 
436  if (ptr != NULL) {
437  // found, check if there is already a writer
438  //instantiate new interface for given memory chunk
439  ih = (interface_header_t *)ptr;
440  if (ih->flag_writer_active) {
441  throw BlackBoardWriterActiveException(identifier, type);
442  }
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)) {
447  }
448  iface->set_memory(ih->serial, ptr, (char *)ptr + sizeof(interface_header_t));
449  rwlocks[ih->serial]->ref();
450  } else {
451  created = true;
452  create_interface(type, identifier, owner, iface, ptr);
453  ih = (interface_header_t *)ptr;
454  }
455 
456  owner_info_[iface->uid()].writer = iface;
457  iface->set_readwrite(true, rwlocks[ih->serial]);
458  ih->flag_writer_active = 1;
459  ih->refcount++;
460 
461  memmgr->unlock();
462  writer_interfaces[ih->serial] = iface;
463 
464  mutex->unlock();
465 
466  if (created) {
467  notifier->notify_of_interface_created(type, identifier);
468  }
469  notifier->notify_of_writer_added(iface, iface->serial());
470  } catch (Exception &e) {
471  if (iface)
472  delete_interface_instance(iface);
473  memmgr->unlock();
474  mutex->unlock();
475  throw;
476  }
477 
478  return iface;
479 }
480 
481 /** Close interface.
482  * @param interface interface to close
483  */
484 void
486 {
487  if (interface == NULL)
488  return;
489  mutex->lock();
490  bool destroyed = false;
491 
492  // reduce refcount and free memory if refcount is zero
493  interface_header_t *ih = (interface_header_t *)interface->mem_real_ptr_;
494  bool killed_writer = interface->write_access_;
495  if (--(ih->refcount) == 0) {
496  // redeem from memory
497  if (interface->write_access_) {
498  writer_interfaces.erase(interface->mem_serial_);
499  }
500  memmgr->free(interface->mem_real_ptr_);
501  destroyed = true;
502  } else {
503  if (interface->write_access_) {
504  ih->flag_writer_active = 0;
505  writer_interfaces.erase(interface->mem_serial_);
506  } else {
507  ih->num_readers--;
508  }
509  }
510 
511  mutex->unlock();
512  if (killed_writer) {
513  notifier->notify_of_writer_removed(interface, interface->serial());
514  } else {
515  notifier->notify_of_reader_removed(interface, interface->serial());
516  }
517  if (destroyed) {
518  notifier->notify_of_interface_destroyed(interface->type_, interface->id_);
519  }
520 
521  MutexLocker lock(mutex);
522  delete_interface_instance(interface);
523 }
524 
525 /** Get a list of interfaces.
526  * @return list of currently existing interfaces. List may be outdated on
527  * return since there maybe concurrent actions.
528  */
531 {
532  InterfaceInfoList *infl = new InterfaceInfoList();
533 
534  memmgr->lock();
535  interface_header_t * ih;
537  for (cit = memmgr->begin(); cit != memmgr->end(); ++cit) {
538  ih = (interface_header_t *)*cit;
540  (Interface::interface_data_ts_t *)((char *)*cit + sizeof(interface_header_t));
541  char type[INTERFACE_TYPE_SIZE_ + 1];
542  char id[INTERFACE_ID_SIZE_ + 1];
543  // ensure NULL-termination
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;
549  infl->append(ih->type,
550  ih->id,
551  ih->hash,
552  ih->serial,
553  ih->flag_writer_active,
554  ih->num_readers,
555  readers(uid),
556  writer(uid),
557  Time(data_ts->timestamp_sec, data_ts->timestamp_usec));
558  }
559 
560  memmgr->unlock();
561 
562  return infl;
563 }
564 
565 /** Get a constrained list of interfaces.
566  * @param type_pattern tyoe pattern, may contain shell-like wildcards * (any number
567  * of characters) and ? (one character), cf. man fnmatch().
568  * @param id_pattern ID pattern, may contain shell-like wildcards * (any number
569  * of characters) and ? (one character), cf. man fnmatch().
570  * @return list of currently existing interfaces matching the given type and
571  * ID patterns. List may be outdated on return since there maybe concurrent
572  * actions.
573  */
575 BlackBoardInterfaceManager::list(const char *type_pattern, 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  std::string uid = std::string(type) + "::" + id;
596  infl->append(ih->type,
597  ih->id,
598  ih->hash,
599  ih->serial,
600  ih->flag_writer_active,
601  ih->num_readers,
602  readers(uid),
603  writer(uid),
604  fawkes::Time(data_ts->timestamp_sec, data_ts->timestamp_usec));
605  }
606  }
607 
608  memmgr->unlock();
609 
610  return infl;
611 }
612 
613 /** Get the writer interface for the given mem serial.
614  * @param mem_serial memory serial to get writer for
615  * @return writer interface for given mem serial, or NULL if non exists
616  * @exception BlackBoardNoWritingInstanceException thrown if no writer
617  * was found for the given interface.
618  */
619 Interface *
620 BlackBoardInterfaceManager::writer_for_mem_serial(unsigned int mem_serial)
621 {
622  if (writer_interfaces.find(mem_serial) != writer_interfaces.end()) {
623  return writer_interfaces[mem_serial];
624  } else {
625  char type[INTERFACE_TYPE_SIZE_ + 1] = "Unknown";
626  char id[INTERFACE_ID_SIZE_ + 1] = "Invalid";
627  // ensure NULL-termination
628  type[INTERFACE_TYPE_SIZE_] = 0;
629  id[INTERFACE_ID_SIZE_] = 0;
630  std::string uid = "Unknown::Invalid";
631  memmgr->lock();
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_);
638  break;
639  }
640  }
641  memmgr->unlock();
642  throw BlackBoardNoWritingInstanceException(type, id);
643  }
644 }
645 
646 void
648 {
649  notifier->notify_of_data_change(interface);
650 }
651 
652 bool
654 {
655  return (writer_interfaces.find(interface->mem_serial_) != writer_interfaces.end());
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 std::string
683 {
684  std::string rv;
685  owner_info_.lock();
687  if ((info = owner_info_.find(interface->uid())) != owner_info_.end()) {
688  if (info->second.writer) {
689  rv = info->second.writer->owner();
690  }
691  }
692  owner_info_.unlock();
693  return rv;
694 }
695 
696 /** Get owners of interfaces who opened for reading.
697  * @param uid UID of interface to query for
698  * @return list of readers for this interface
699  */
700 std::list<std::string>
701 BlackBoardInterfaceManager::readers(const std::string &uid) const
702 {
703  std::list<std::string> rv;
704  owner_info_.lock();
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());
710  }
711  }
712  owner_info_.unlock();
713  return rv;
714 }
715 
716 /** Get writer of interface.
717  * @param uid UID of interface to query for
718  * @return owner name of writing interface instance, or empty string of no writer exists
719  */
720 std::string
721 BlackBoardInterfaceManager::writer(const std::string &uid) const
722 {
723  std::string rv;
724  owner_info_.lock();
726  if ((info = owner_info_.find(uid)) != owner_info_.end()) {
727  if (info->second.writer) {
728  rv = info->second.writer->owner();
729  }
730  }
731  owner_info_.unlock();
732  return rv;
733 }
734 
735 } // end namespace fawkes
fawkes::Mutex::lock
void lock()
Lock this mutex.
Definition: mutex.cpp:87
fawkes::BlackBoardMemoryManager::free
void free(void *chunk_ptr)
Free a memory chunk.
Definition: memory_manager.cpp:332
fawkes::BlackBoardInterfaceManager::BlackBoardInterfaceManager
BlackBoardInterfaceManager(BlackBoardMemoryManager *bb_memmgr, BlackBoardMessageManager *bb_msgmgr, BlackBoardNotifier *bb_notifier)
Constructor.
Definition: interface_manager.cpp:63
fawkes::interface_header_t::refcount
uint32_t refcount
reference count
Definition: interface_mem_header.h:44
fawkes::LockMap
Map with a lock.
Definition: lock_map.h:36
fawkes::Mutex
Mutex mutual exclusion lock.
Definition: mutex.h:33
fawkes::BlackBoardInterfaceManager::writer
virtual std::string writer(const Interface *interface) const
Get writer of interface.
Definition: interface_manager.cpp:682
fawkes::BlackBoardMemoryManager::unlock
void unlock()
Unlock memory.
Definition: memory_manager.cpp:616
fawkes::Interface::interface_data_ts_t
Timestamp data, must be present and first entries for each interface data structs!...
Definition: interface.h:198
fawkes::Interface::hash
const unsigned char * hash() const
Get interface hash.
Definition: interface.cpp:298
fawkes::BlackBoardInterfaceManager::list
InterfaceInfoList * list(const char *type_pattern, const char *id_pattern) const
Get a constrained list of interfaces.
Definition: interface_manager.cpp:575
fawkes::BlackBoardMemoryManager::end
ChunkIterator end()
Get end of chunk list.
Definition: memory_manager.cpp:865
fawkes::MutexLocker
Mutex locking helper.
Definition: mutex_locker.h:34
fawkes::BlackBoardInterfaceManager::open_for_reading
Interface * open_for_reading(const char *interface_type, const char *identifier, const char *owner=NULL)
Open interface for reading.
Definition: interface_manager.cpp:247
fawkes::BlackBoardMemoryManager::is_master
bool is_master() const
Check if this BB memory manager is the master.
Definition: memory_manager.cpp:449
fawkes::interface_header_t::num_readers
uint16_t num_readers
number of active readers
Definition: interface_mem_header.h:43
fawkes::BlackBoardInterfaceManager::~BlackBoardInterfaceManager
virtual ~BlackBoardInterfaceManager()
Destructor.
Definition: interface_manager.cpp:80
fawkes::BlackBoardInterfaceManager::open_for_writing
Interface * open_for_writing(const char *interface_type, const char *identifier, const char *owner=NULL)
Open interface for writing.
Definition: interface_manager.cpp:412
fawkes::BlackBoardMemoryManager::ChunkIterator
Iterator for memory chunks.
Definition: memory_manager.h:105
fawkes::Interface::interface_data_ts_t::timestamp_sec
int64_t timestamp_sec
time in seconds since Unix epoch
Definition: interface.h:199
fawkes::LockMap::unlock
void unlock() const
Unlock list.
Definition: lock_map.h:109
fawkes::Mutex::unlock
void unlock()
Unlock the mutex.
Definition: mutex.cpp:131
fawkes::BlackBoardMemoryManager
BlackBoard memory manager.
Definition: memory_manager.h:59
fawkes::BlackBoardInstanceFactory::delete_interface_instance
void delete_interface_instance(Interface *interface)
Destroy an interface instance.
Definition: instance_factory.cpp:111
fawkes::BlackBoardInterfaceManager::num_readers
virtual unsigned int num_readers(const Interface *interface) const
Get number of readers.
Definition: interface_manager.cpp:659
fawkes::Interface::interface_data_ts_t::timestamp_usec
int64_t timestamp_usec
additional time microseconds
Definition: interface.h:200
fawkes::InterfaceInfoList::append
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.
Definition: interface_info.cpp:260
fawkes::BlackBoardNotifier::notify_of_reader_removed
void notify_of_reader_removed(const Interface *interface, unsigned int event_instance_serial)
Notify that reader has been removed.
Definition: notifier.cpp:626
fawkes::interface_header_t::id
char id[INTERFACE_ID_SIZE_]
interface identifier
Definition: interface_mem_header.h:39
fawkes::BlackBoardMemoryManager::lock
void lock()
Lock memory.
Definition: memory_manager.cpp:581
fawkes
Fawkes library namespace.
fawkes::BlackBoardInterfaceManager::close
void close(Interface *interface)
Close interface.
Definition: interface_manager.cpp:485
fawkes::BlackBoardInterfaceManager::open_multiple_for_reading
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.
Definition: interface_manager.cpp:325
fawkes::InterfaceInfoList
Interface information list.
Definition: interface_info.h:76
fawkes::BlackBoardInterfaceVersionMismatchException
Thrown if versions do not match.
Definition: exceptions.h:112
fawkes::Interface
Base class for all Fawkes BlackBoard interfaces.
Definition: interface.h:79
fawkes::BlackBoardNotifier::notify_of_reader_added
void notify_of_reader_added(const Interface *interface, unsigned int event_instance_serial)
Notify that reader has been added.
Definition: notifier.cpp:589
fawkes::BlackBoardInterfaceManager::list_all
InterfaceInfoList * list_all() const
Get a list of interfaces.
Definition: interface_manager.cpp:530
fawkes::BlackBoardMessageManager
BlackBoard message manager.
Definition: message_manager.h:37
fawkes::Interface::uid
const char * uid() const
Get unique identifier of interface.
Definition: interface.cpp:677
fawkes::BlackBoardNotifier::notify_of_writer_added
void notify_of_writer_added(const Interface *interface, unsigned int event_instance_serial)
Notify that writer has been added.
Definition: notifier.cpp:495
fawkes::interface_header_t::type
char type[INTERFACE_TYPE_SIZE_]
interface type
Definition: interface_mem_header.h:38
fawkes::Time
A class for handling time.
Definition: time.h:93
fawkes::BlackBoardNotifier::notify_of_interface_created
void notify_of_interface_created(const char *type, const char *id)
Notify that an interface has been created.
Definition: notifier.cpp:401
fawkes::BlackBoardNotifier::notify_of_data_change
void notify_of_data_change(const Interface *interface)
Notify of data change.
Definition: notifier.cpp:687
fawkes::BlackBoardMemoryManager::begin
ChunkIterator begin()
Get first element for chunk iteration.
Definition: memory_manager.cpp:850
fawkes::BlackBoardInstanceFactory
BlackBoard instance factory.
Definition: instance_factory.h:34
fawkes::BlackBoardInstanceFactory::new_interface_instance
Interface * new_interface_instance(const char *type, const char *identifier)
Creates a new interface instance.
Definition: instance_factory.cpp:66
fawkes::Interface::serial
unsigned short serial() const
Get instance serial of interface.
Definition: interface.cpp:686
fawkes::BlackBoardInterfaceManager::notify_of_data_change
virtual void notify_of_data_change(const Interface *interface)
Notify of data change.
Definition: interface_manager.cpp:647
fawkes::BlackBoardNotifier
BlackBoard notifier.
Definition: notifier.h:43
fawkes::interface_header_t::flag_writer_active
uint16_t flag_writer_active
1 if there is a writer, 0 otherwise
Definition: interface_mem_header.h:41
fawkes::BlackBoardInterfaceManager::exists_writer
virtual bool exists_writer(const Interface *interface) const
Check if a writer exists for the given interface.
Definition: interface_manager.cpp:653
fawkes::BlackBoardInterfaceManager::readers
virtual std::list< std::string > readers(const Interface *interface) const
Get owners of interfaces who opened for reading.
Definition: interface_manager.cpp:666
fawkes::interface_header_t::serial
uint32_t serial
memory serial
Definition: interface_mem_header.h:45
fawkes::LockMap::lock
void lock() const
Lock list.
Definition: lock_map.h:91
fawkes::interface_header_t
This struct is used as header for interfaces in memory chunks.
Definition: interface_mem_header.h:37
fawkes::BlackBoardNotifier::notify_of_interface_destroyed
void notify_of_interface_destroyed(const char *type, const char *id)
Notify that an interface has been destroyed.
Definition: notifier.cpp:436
fawkes::Interface::hash_size
size_t hash_size() const
Get size of interface hash.
Definition: interface.cpp:419
fawkes::BlackBoardNotifier::notify_of_writer_removed
void notify_of_writer_removed(const Interface *interface, unsigned int event_instance_serial)
Notify that writer has been removed.
Definition: notifier.cpp:532
fawkes::interface_header_t::hash
unsigned char hash[INTERFACE_HASH_SIZE_]
interface type version hash
Definition: interface_mem_header.h:40
fawkes::BlackBoardWriterActiveException
Thrown if a writer is already active on an interface that writing has been requested for.
Definition: exceptions.h:125
fawkes::Exception
Base class for exceptions in Fawkes.
Definition: exception.h:36