@@ -110,23 +110,28 @@ struct ModuleService::ServiceImpl : viam::module::v1::ModuleService::Service {
110110 }
111111 auto manager = resource_server->resource_manager ();
112112
113- // see if our resource is reconfigurable. if it is, reconfigure
114- const std::shared_ptr<Resource> res = manager->resource (cfg.resource_name ().name ());
115- if (!res) {
116- return grpc::Status (grpc::UNKNOWN,
117- " unable to reconfigure resource " + cfg.resource_name ().name () +
118- " as it doesn't exist." );
119- }
113+ // Explicitly open a scope to control the lifetime of the shared_ptr<Resource>, otherwise
114+ // `res` below will keep the refcount high until the function exits, fouling up the order of
115+ // operations for replacing a resource.
116+ {
117+ // see if our resource is reconfigurable. if it is, reconfigure
118+ const std::shared_ptr<Resource> res = manager->resource (cfg.resource_name ().name ());
119+ if (!res) {
120+ return grpc::Status (grpc::UNKNOWN,
121+ " unable to reconfigure resource " + cfg.resource_name ().name () +
122+ " as it doesn't exist." );
123+ }
120124
121- if (auto reconfigurable = std::dynamic_pointer_cast<Reconfigurable>(res)) {
122- reconfigurable->reconfigure (deps, cfg);
123- res->set_log_level (cfg.get_log_level ());
124- return grpc::Status ();
125- }
125+ if (auto reconfigurable = std::dynamic_pointer_cast<Reconfigurable>(res)) {
126+ reconfigurable->reconfigure (deps, cfg);
127+ res->set_log_level (cfg.get_log_level ());
128+ return grpc::Status ();
129+ }
126130
127- // if the type isn't reconfigurable by default, replace it
128- if (auto stoppable = std::dynamic_pointer_cast<Stoppable>(res)) {
129- stoppable->stop ();
131+ // if the type isn't reconfigurable by default, replace it
132+ if (auto stoppable = std::dynamic_pointer_cast<Stoppable>(res)) {
133+ stoppable->stop ();
134+ }
130135 }
131136
132137 const std::shared_ptr<const ModelRegistration> reg =
@@ -138,8 +143,9 @@ struct ModuleService::ServiceImpl : viam::module::v1::ModuleService::Service {
138143 }
139144
140145 try {
141- std::shared_ptr<Resource> resource = reg->construct_resource (deps, cfg);
142- manager->replace_one (cfg.resource_name (), std::move (resource));
146+ manager->replace_one (cfg.resource_name (), [®, &deps, &cfg]() {
147+ return reg->construct_resource (deps, cfg);
148+ });
143149 } catch (const std::exception& exc) {
144150 return grpc::Status (::grpc::INTERNAL, exc.what ());
145151 }
0 commit comments