@@ -98,6 +98,7 @@ void module_register(struct module *module_data, struct module *parent)
9898 struct module_priv_state * module_priv = calloc (1 , sizeof * module_data -> module_priv );
9999 module_data -> module_priv = module_priv ;
100100 module_priv -> magic = MODULE_MAGIC ;
101+ module_priv -> ref = 1 ;
101102 memcpy (& module_priv -> wrapper , module_data , sizeof * module_data );
102103
103104 int ret = 0 ;
@@ -122,35 +123,31 @@ void module_register(struct module *module_data, struct module *parent)
122123 module_mutex_lock (& parent -> module_priv -> lock );
123124 simple_linked_list_append (parent -> module_priv -> children , module_priv );
124125 module_check_undelivered_messages (parent );
126+ module_priv -> parent -> ref += 1 ;
125127 module_mutex_unlock (& parent -> module_priv -> lock );
126128}
127129
128- static void
130+ static bool
129131module_del_ref (struct module_priv_state * module_priv )
130132{
131133 assert (module_priv -> magic == MODULE_MAGIC );
132134
135+ module_mutex_lock (& module_priv -> lock );
136+ const int new_ref = module_priv -> ref -= 1 ;
137+ module_mutex_unlock (& module_priv -> lock );
138+ if (new_ref > 0 ) {
139+ return false;
140+ }
141+
133142 if (module_priv -> parent ) {
134143 module_mutex_lock (& module_priv -> parent -> lock );
135144 bool found = simple_linked_list_remove (
136145 module_priv -> parent -> children , module_priv );
137146 assert (found );
138147 module_mutex_unlock (& module_priv -> parent -> lock );
148+ module_del_ref (module_priv -> parent );
139149 }
140150
141- if (simple_linked_list_size (module_priv -> children ) > 0 ) {
142- log_msg (LOG_LEVEL_WARNING , "Warning: Child database not empty! Remaining:\n" );
143- dump_tree (& module_priv -> wrapper , 0 );
144- module_mutex_lock (& module_priv -> lock );
145- for (void * it = simple_linked_list_it_init (module_priv -> children ); it != NULL ; ) {
146- struct module_priv_state * child = simple_linked_list_it_next (& it );
147- assert (child -> magic == MODULE_MAGIC );
148- module_mutex_lock (& child -> lock );
149- child -> parent = NULL ;
150- module_mutex_unlock (& child -> lock );
151- }
152- module_mutex_unlock (& module_priv -> lock );
153- }
154151 simple_linked_list_destroy (module_priv -> children );
155152
156153 if (simple_linked_list_size (module_priv -> msg_queue ) > 0 ) {
@@ -174,6 +171,7 @@ module_del_ref(struct module_priv_state *module_priv)
174171
175172 pthread_mutex_destroy (& module_priv -> lock );
176173 free (module_priv );
174+ return true;
177175}
178176
179177void
@@ -187,7 +185,10 @@ module_done(struct module *module_data)
187185 return ;
188186 }
189187 struct module_priv_state * module_priv = module_data -> module_priv ;
190- module_del_ref (module_priv );
188+ if (!module_del_ref (module_priv )) {
189+ log_msg (LOG_LEVEL_WARNING , "Warning: Child database not empty! Remaining:\n" );
190+ dump_tree (& module_priv -> wrapper , 0 );
191+ }
191192 module_data -> module_priv = NULL ; // to avoid multiple deinit
192193}
193194
0 commit comments