/** 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; }
/** 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; }
/** 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; }