X-Git-Url: https://wimlib.net/git/?a=blobdiff_plain;f=src%2Fwim.c;h=b5827171ba91e139d9f7a5c83cc756d8b08041c0;hb=6212b224b8c0caaf0ac88af54976b87cd377ad7d;hp=e77d71704ece213305bf3b45e878793692e19813;hpb=00d7680491529e7fd95f5721bd01795a730fc440;p=wimlib diff --git a/src/wim.c b/src/wim.c index e77d7170..b5827171 100644 --- a/src/wim.c +++ b/src/wim.c @@ -146,12 +146,12 @@ new_wim_struct(void) if (!wim) return NULL; + wim->refcnt = 1; filedes_invalidate(&wim->in_fd); filedes_invalidate(&wim->out_fd); wim->out_solid_compression_type = wim_default_solid_compression_type(); wim->out_solid_chunk_size = wim_default_solid_chunk_size( wim->out_solid_compression_type); - INIT_LIST_HEAD(&wim->subwims); return wim; } @@ -867,38 +867,45 @@ can_modify_wim(WIMStruct *wim) return 0; } -/* API function documented in wimlib.h */ -WIMLIBAPI void -wimlib_free(WIMStruct *wim) +/* Release a reference to a WIMStruct. If the reference count reaches 0, the + * WIMStruct is freed. */ +void +wim_decrement_refcnt(WIMStruct *wim) { - if (!wim) + wimlib_assert(wim->refcnt > 0); + if (--wim->refcnt != 0) return; - - while (!list_empty(&wim->subwims)) { - WIMStruct *subwim; - - subwim = list_entry(wim->subwims.next, WIMStruct, subwim_node); - list_del(&subwim->subwim_node); - wimlib_free(subwim); - } - if (filedes_valid(&wim->in_fd)) filedes_close(&wim->in_fd); if (filedes_valid(&wim->out_fd)) filedes_close(&wim->out_fd); + wimlib_free_decompressor(wim->decompressor); + xml_free_info_struct(wim->xml_info); + FREE(wim->filename); + FREE(wim); +} - free_blob_table(wim->blob_table); +/* API function documented in wimlib.h */ +WIMLIBAPI void +wimlib_free(WIMStruct *wim) +{ + if (!wim) + return; - wimlib_free_decompressor(wim->decompressor); + /* The blob table and image metadata are freed immediately, but other + * members of the WIMStruct such as the input file descriptor are + * retained until no more exported resources reference the WIMStruct. */ - FREE(wim->filename); - xml_free_info_struct(wim->xml_info); - if (wim->image_metadata) { - for (unsigned i = 0; i < wim->hdr.image_count; i++) + free_blob_table(wim->blob_table); + wim->blob_table = NULL; + if (wim->image_metadata != NULL) { + for (int i = 0; i < wim->hdr.image_count; i++) put_image_metadata(wim->image_metadata[i], NULL); FREE(wim->image_metadata); + wim->image_metadata = NULL; } - FREE(wim); + + wim_decrement_refcnt(wim); } static bool