@@ -116,7 +116,6 @@ class engine : public margo_instance_ref {
116116 m_mid = margo_init_ext (addr.c_str (), mode, args);
117117 if (!m_mid)
118118 MARGO_THROW (margo_init_ext, HG_OTHER_ERROR, " Could not initialize Margo" );
119- margo_instance_ref_incr (m_mid);
120119 }
121120
122121 /* *
@@ -148,7 +147,6 @@ class engine : public margo_instance_ref {
148147 m_mid = margo_init_ext (addr.c_str (), mode, &args);
149148 if (!m_mid)
150149 MARGO_THROW (margo_init_ext, HG_OTHER_ERROR, " Could not initialize Margo" );
151- margo_instance_ref_incr (m_mid);
152150 }
153151
154152 /* *
@@ -171,7 +169,6 @@ class engine : public margo_instance_ref {
171169 m_mid = margo_init_ext (addr.c_str (), mode, &args);
172170 if (!m_mid)
173171 MARGO_THROW (margo_init_ext, HG_OTHER_ERROR, " Could not initialize Margo" );
174- margo_instance_ref_incr (m_mid);
175172 }
176173
177174 engine (const std::string& addr, int mode,
@@ -183,9 +180,20 @@ class engine : public margo_instance_ref {
183180
184181 /* *
185182 * @brief Builds an engine around an existing margo instance.
183+ *
184+ * If take_ownership is false, this new instance of engine will increase
185+ * the margo_instance_id's reference count by 1, leaving it the same as
186+ * before when the destructor is called. The caller is responsible for
187+ * releasing and/or finalizing the margo instance themselves.
188+ *
189+ * If take_ownership is true, the engine will NOT increase the margo
190+ * instance's reference count, hence taking responsibility for releasing
191+ * it.
192+ *
193+ * @important only one engine can every take ownership of a margo instance.
186194 */
187- engine (margo_instance_id mid) noexcept
188- : margo_instance_ref(mid) {}
195+ engine (margo_instance_id mid, bool take_ownership = false ) noexcept
196+ : margo_instance_ref(mid, take_ownership ) {}
189197
190198 /* *
191199 * @brief Copy-constructor.
@@ -233,6 +241,13 @@ class engine : public margo_instance_ref {
233241 */
234242 void finalize () {
235243 MARGO_INSTANCE_MUST_BE_VALID;
244+ // note: we increment the reference count before finalizing.
245+ // margo_finalize will decrement it back. This ensures that
246+ // margo_finalize will not cause the instance to be freed, so
247+ // margo_instance_release can safely be called in the engine's
248+ // destructor, or in the destructor of any other object referencing
249+ // the margo instance.
250+ margo_instance_ref_incr (m_mid);
236251 margo_finalize (m_mid);
237252 }
238253
@@ -251,6 +266,13 @@ class engine : public margo_instance_ref {
251266 */
252267 void finalize_and_wait () {
253268 MARGO_INSTANCE_MUST_BE_VALID;
269+ // note: we increment the reference count before finalizing.
270+ // margo_finalize_and_wait will decrement it back. This ensures that
271+ // margo_finalize_and_wait will not cause the instance to be freed, so
272+ // margo_instance_release can safely be called in the engine's
273+ // destructor, or in the destructor of any other object referencing
274+ // the margo instance.
275+ margo_instance_ref_incr (m_mid);
254276 margo_finalize_and_wait (m_mid);
255277 }
256278
@@ -1016,7 +1038,6 @@ inline engine::engine(const std::string& addr, int mode, const pool& progress_po
10161038 m_mid = margo_init_ext (addr.c_str (), mode, &args);
10171039 if (!m_mid)
10181040 MARGO_THROW (margo_init_ext, HG_OTHER_ERROR, " Could not initialize Margo" );
1019- margo_instance_ref_incr (m_mid);
10201041}
10211042
10221043template <typename T1, typename ... Tn>
0 commit comments