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