/** Open interface for writing.
 * This will create a new interface instance of the given type. The result can be
 * casted to the appropriate type. This will only succeed if there is not already
 * a writer for the given interface type/id!
 * @param type type of the interface
 * @param identifier identifier of the interface
 * @return new fully initialized interface instance of requested type
 * @exception OutOfMemoryException thrown if there is not enough free space for
 * the requested interface.
 * @exception BlackBoardWriterActiveException thrown if there is already a writing
 * instance with the same type/id
 */
Interface *
BlackBoardInterfaceManager::open_for_writing(const char *type, const char *identifier)
{
  mutex->lock();
  memmgr->lock();

  Interface *iface = NULL;
  void *ptr = NULL;
  interface_header_t *ih;
  bool created = false;

  try {
    ptr = find_interface_in_memory(type, identifier);

    if ( ptr != NULL ) {
      // found, check if there is already a writer
      //instantiate new interface for given memory chunk
      ih  = (interface_header_t *)ptr;
      if ( ih->flag_writer_active ) {
	throw BlackBoardWriterActiveException(identifier, type);
      }
      iface = new_interface_instance(type, identifier);
      if ( (iface->hash_size() != __INTERFACE_HASH_SIZE ) ||
	   (memcmp(iface->hash(), ih->hash, __INTERFACE_HASH_SIZE) != 0) ) {
	throw BlackBoardInterfaceVersionMismatchException();
      }
      iface->set_memory(ih->serial, ptr, (char *)ptr + sizeof(interface_header_t));
      rwlocks[ih->serial]->ref();
    } else {
      created = true;
      create_interface(type, identifier, iface, ptr);
      ih = (interface_header_t *)ptr;
    }

    iface->set_readwrite(true, rwlocks[ih->serial]);
    ih->flag_writer_active = 1;
    ih->refcount++;

    memmgr->unlock();
    writer_interfaces[ih->serial] = iface;

    mutex->unlock();

    if ( created ) {
      notifier->notify_of_interface_created(type, identifier);
    }
    notifier->notify_of_writer_added(iface, iface->serial());
  } catch (Exception &e) {
    if (iface)  delete_interface_instance(iface);
    memmgr->unlock();
    mutex->unlock();
    throw;
  }

  return iface;
}
Пример #2
0
/** Open all interfaces of the given type for reading.
 * This will create interface instances for all currently registered interfaces of
 * the given type. The result can be casted to the appropriate type.
 * @param type_pattern pattern of interface types to open, supports wildcards
 * similar to filenames (*, ?, []), see "man fnmatch" for all supported.
 * @param id_pattern pattern of interface IDs to open, supports wildcards similar
 * to filenames (*, ?, []), see "man fnmatch" for all supported.
 * @param owner name of entity which opened this interface. If using the BlackBoardAspect
 * to access the blackboard leave this untouched unless you have a good reason.
 * @return list of new fully initialized interface instances of requested type. The
 * is allocated using new and you have to free it using delete after you are done
 * with it!
 */
std::list<Interface *>
BlackBoardInterfaceManager::open_multiple_for_reading(const char *type_pattern,
						      const char *id_pattern,
						      const char *owner)
{
  mutex->lock();
  memmgr->lock();

  std::list<Interface *> rv;

  Interface *iface = NULL;
  interface_header_t *ih;
  BlackBoardMemoryManager::ChunkIterator cit;

  try {
    for ( cit = memmgr->begin(); cit != memmgr->end(); ++cit ) {
      iface = NULL;
      ih = (interface_header_t *)*cit;

      // ensure 0-termination
      char type[__INTERFACE_TYPE_SIZE + 1];
      char id[__INTERFACE_ID_SIZE + 1];
      type[__INTERFACE_TYPE_SIZE] = 0;
      id[__INTERFACE_TYPE_SIZE] = 0;
      strncpy(type, ih->type, __INTERFACE_TYPE_SIZE);
      strncpy(id, ih->id, __INTERFACE_ID_SIZE);

      if ((fnmatch(type_pattern, type, 0) == FNM_NOMATCH) ||
	  (fnmatch(id_pattern, id, 0) == FNM_NOMATCH) ) {
	// type or ID prefix does not match, go on
	continue;
      }

      void *ptr = *cit;
      iface = new_interface_instance(ih->type, ih->id, owner);
      iface->set_memory(ih->serial, ptr, (char *)ptr + sizeof(interface_header_t));

      if ( (iface->hash_size() != __INTERFACE_HASH_SIZE ) ||
	   (memcmp(iface->hash(), ih->hash, __INTERFACE_HASH_SIZE) != 0) ) {
	throw BlackBoardInterfaceVersionMismatchException();
      }

      rwlocks[ih->serial]->ref();

      owner_info_[iface->uid()].readers.push_back(iface);
      iface->set_readwrite(false, rwlocks[ih->serial]);
      ih->refcount++;
      ih->num_readers++;

      rv.push_back(iface);
    }

    mutex->unlock();
    memmgr->unlock();

    for (std::list<Interface *>::iterator j = rv.begin(); j != rv.end(); ++j) {
      notifier->notify_of_reader_added(*j, (*j)->serial());
    }


  } catch (Exception &e) {
    if (iface)  delete_interface_instance( iface );
    for (std::list<Interface *>::iterator i = rv.begin(); i != rv.end(); ++i) {
      delete_interface_instance(*i);
    }
    memmgr->unlock();
    mutex->unlock();
    throw;
  }

  return rv;
}
Пример #3
0
/** Open interface for reading.
 * This will create a new interface instance of the given type. The result can be
 * casted to the appropriate type.
 * @param type type of the interface
 * @param identifier identifier of the interface
 * @param owner name of entity which opened this interface. If using the BlackBoardAspect
 * to access the blackboard leave this untouched unless you have a good reason.
 * @return new fully initialized interface instance of requested type
 * @exception OutOfMemoryException thrown if there is not enough free space for
 * the requested interface.
 */
Interface *
BlackBoardInterfaceManager::open_for_reading(const char *type, const char *identifier, const char *owner)
{
  if (strlen(type) > __INTERFACE_TYPE_SIZE) {
    throw Exception("Interface type '%s' too long, maximum length is %zu",
		    type, __INTERFACE_TYPE_SIZE);
  }
  if (strlen(identifier) > __INTERFACE_ID_SIZE) {
    throw Exception("Interface ID '%s' too long, maximum length is %zu",
		    type, __INTERFACE_ID_SIZE);
  }

  mutex->lock();
  Interface *iface = NULL;
  void *ptr = NULL;
  interface_header_t *ih;
  bool created = false;

  memmgr->lock();

  ptr = find_interface_in_memory(type, identifier);

  try {
    if ( ptr != NULL ) {
      // found, instantiate new interface for given memory chunk
      iface = new_interface_instance(type, identifier, owner);
      ih  = (interface_header_t *)ptr;
      if ( (iface->hash_size() != __INTERFACE_HASH_SIZE ) ||
	   (memcmp(iface->hash(), ih->hash, __INTERFACE_HASH_SIZE) != 0) ) {
	throw BlackBoardInterfaceVersionMismatchException();
      }
      iface->set_memory(ih->serial, ptr, (char *)ptr + sizeof(interface_header_t));
      rwlocks[ih->serial]->ref();
    } else {
      created = true;
      create_interface(type, identifier, owner, iface, ptr);
      ih  = (interface_header_t *)ptr;
    }

    owner_info_[iface->uid()].readers.push_back(iface);
    iface->set_readwrite(false, rwlocks[ih->serial]);
    ih->refcount++;
    ih->num_readers++;

    memmgr->unlock();
    mutex->unlock();

    if ( created ) {
      notifier->notify_of_interface_created(type, identifier);
    }
    notifier->notify_of_reader_added(iface, iface->serial());

  } catch (Exception &e) {
    if (iface)  delete_interface_instance(iface);
    memmgr->unlock();
    mutex->unlock();
    throw;
  }

  return iface;
}