X-Git-Url: https://wimlib.net/git/?a=blobdiff_plain;f=src%2Fwim.c;h=43b25aca950d7e1aecac523de7fc73399d0274a0;hb=4109848cdf4c31d8ea1a410b183478ad4124f15b;hp=e77d71704ece213305bf3b45e878793692e19813;hpb=00d7680491529e7fd95f5721bd01795a730fc440;p=wimlib diff --git a/src/wim.c b/src/wim.c index e77d7170..43b25aca 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; } @@ -177,7 +177,7 @@ wimlib_create_new_wim(enum wimlib_compression_type ctype, WIMStruct **wim_ret) return WIMLIB_ERR_NOMEM; wim->xml_info = xml_new_info_struct(); - wim->blob_table = new_blob_table(9001); + wim->blob_table = new_blob_table(64); if (!wim->xml_info || !wim->blob_table) { wimlib_free(wim); return WIMLIB_ERR_NOMEM; @@ -729,7 +729,7 @@ begin_read(WIMStruct *wim, const void *wim_filename_or_fd, int open_flags) } if (open_flags & WIMLIB_OPEN_FLAG_FROM_PIPE) { - wim->blob_table = new_blob_table(9001); + wim->blob_table = new_blob_table(64); if (!wim->blob_table) return WIMLIB_ERR_NOMEM; } else { @@ -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