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 /** 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  */
184 void
185 BlackBoardInterfaceManager::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  */
232 Interface *
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;
249  interface_header_t *ih;
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  */
310 std::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;
321  interface_header_t * ih;
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  */
397 Interface *
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;
416  interface_header_t *ih;
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  */
470 void
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 {
518  InterfaceInfoList *infl = new InterfaceInfoList();
519 
520  memmgr->lock();
521  interface_header_t * ih;
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,
539  ih->flag_writer_active,
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  */
561 BlackBoardInterfaceManager::list(const char *type_pattern, const char *id_pattern) const
562 {
563  InterfaceInfoList *infl = new InterfaceInfoList();
564 
565  memmgr->lock();
566  interface_header_t * ih;
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,
586  ih->flag_writer_active,
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  */
605 Interface *
606 BlackBoardInterfaceManager::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 
632 void
634 {
635  notifier->notify_of_data_refresh(interface, has_changed);
636 }
637 
638 bool
640 {
641  return (writer_interfaces.find(interface->mem_serial_) != writer_interfaces.end());
642 }
643 
644 unsigned int
646 {
647  const interface_header_t *ih = (interface_header_t *)interface->mem_real_ptr_;
648  return ih->num_readers;
649 }
650 
651 std::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 
667 std::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  */
686 std::list<std::string>
687 BlackBoardInterfaceManager::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  */
706 std::string
707 BlackBoardInterfaceManager::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