@@ -148,6 +148,7 @@ int sd_netlink_inc_rcvbuf(sd_netlink *rtnl, size_t size) {
148148}
149149
150150static sd_netlink * netlink_free (sd_netlink * rtnl ) {
151+ struct reply_callback * c ;
151152 struct match_callback * f ;
152153 unsigned i ;
153154
@@ -163,7 +164,12 @@ static sd_netlink *netlink_free(sd_netlink *rtnl) {
163164
164165 free (rtnl -> rbuffer );
165166
166- hashmap_free_free (rtnl -> reply_callbacks );
167+ while ((c = hashmap_steal_first (rtnl -> reply_callbacks ))) {
168+ if (c -> destroy_callback )
169+ c -> destroy_callback (c -> userdata );
170+ free (c );
171+ }
172+ hashmap_free (rtnl -> reply_callbacks );
167173 prioq_free (rtnl -> reply_callbacks_prioq );
168174
169175 sd_event_source_unref (rtnl -> io_event_source );
@@ -299,6 +305,9 @@ static int process_timeout(sd_netlink *rtnl) {
299305 if (r < 0 )
300306 log_debug_errno (r , "sd-netlink: timedout callback failed: %m" );
301307
308+ if (c -> destroy_callback )
309+ c -> destroy_callback (c -> userdata );
310+
302311 free (c );
303312
304313 return 1 ;
@@ -332,6 +341,9 @@ static int process_reply(sd_netlink *rtnl, sd_netlink_message *m) {
332341 if (r < 0 )
333342 log_debug_errno (r , "sd-netlink: callback failed: %m" );
334343
344+ if (c -> destroy_callback )
345+ c -> destroy_callback (c -> userdata );
346+
335347 return 1 ;
336348}
337349
@@ -494,13 +506,15 @@ static int timeout_compare(const void *a, const void *b) {
494506 return CMP (x -> timeout , y -> timeout );
495507}
496508
497- int sd_netlink_call_async (sd_netlink * nl ,
498- sd_netlink_message * m ,
499- sd_netlink_message_handler_t callback ,
500- void * userdata ,
501- uint64_t usec ,
502- uint32_t * serial ) {
503- struct reply_callback * c ;
509+ int sd_netlink_call_async (
510+ sd_netlink * nl ,
511+ sd_netlink_message * m ,
512+ sd_netlink_message_handler_t callback ,
513+ sd_netlink_destroy_t destroy_callback ,
514+ void * userdata ,
515+ uint64_t usec ,
516+ uint32_t * serial ) {
517+ _cleanup_free_ struct reply_callback * c = NULL ;
504518 uint32_t s ;
505519 int r , k ;
506520
@@ -519,40 +533,40 @@ int sd_netlink_call_async(sd_netlink *nl,
519533 return r ;
520534 }
521535
522- c = new0 (struct reply_callback , 1 );
536+ c = new (struct reply_callback , 1 );
523537 if (!c )
524538 return - ENOMEM ;
525539
526- c -> callback = callback ;
527- c -> userdata = userdata ;
528- c -> timeout = calc_elapse (usec );
540+ * c = (struct reply_callback ) {
541+ .callback = callback ,
542+ .userdata = userdata ,
543+ .timeout = calc_elapse (usec ),
544+ .destroy_callback = destroy_callback ,
545+ };
529546
530547 k = sd_netlink_send (nl , m , & s );
531- if (k < 0 ) {
532- free (c );
548+ if (k < 0 )
533549 return k ;
534- }
535550
536551 c -> serial = s ;
537552
538553 r = hashmap_put (nl -> reply_callbacks , & c -> serial , c );
539- if (r < 0 ) {
540- free (c );
554+ if (r < 0 )
541555 return r ;
542- }
543556
544557 if (c -> timeout != 0 ) {
545558 r = prioq_put (nl -> reply_callbacks_prioq , c , & c -> prioq_idx );
546559 if (r < 0 ) {
547- c -> timeout = 0 ;
548- sd_netlink_call_async_cancel (nl , c -> serial );
560+ (void ) hashmap_remove (nl -> reply_callbacks , & c -> serial );
549561 return r ;
550562 }
551563 }
552564
553565 if (serial )
554566 * serial = s ;
555567
568+ TAKE_PTR (c );
569+
556570 return k ;
557571}
558572
@@ -571,6 +585,9 @@ int sd_netlink_call_async_cancel(sd_netlink *nl, uint32_t serial) {
571585 if (c -> timeout != 0 )
572586 prioq_remove (nl -> reply_callbacks_prioq , c , & c -> prioq_idx );
573587
588+ if (c -> destroy_callback )
589+ c -> destroy_callback (c -> userdata );
590+
574591 free (c );
575592 return 1 ;
576593}
0 commit comments