diff options
author | Ray Johnston <ray.johnston@artifex.com> | 2012-05-09 22:01:46 -0700 |
---|---|---|
committer | Ray Johnston <ray.johnston@artifex.com> | 2012-05-09 22:01:46 -0700 |
commit | c6d74690be87eb37ca5b4590ed6b44673e4125c7 (patch) | |
tree | 02bce492dc31637172f14b2d1c46fe52b95571a7 | |
parent | 055ed5f7a69ad5cf4181cf337abf2245df668c01 (diff) |
Fix bug 692372 and bug 693001 to free semaphores without leaking memory.
The original fix (fe8d7b6) for 692372 released the semaphores, but resulted
in memory leaks of many other parts of the imager state. The leak was fixed
by reverting the above change. This change insures that sempahores are not
leaked by adding 'finalization' to the icc_linkcache and icc_link structs.
-rw-r--r-- | gs/base/gsicc_cache.c | 37 | ||||
-rw-r--r-- | gs/base/gsistate.c | 3 | ||||
-rw-r--r-- | gs/base/gsstruct.h | 118 |
3 files changed, 153 insertions, 5 deletions
diff --git a/gs/base/gsicc_cache.c b/gs/base/gsicc_cache.c index 32f148e43..d06aa868b 100644 --- a/gs/base/gsicc_cache.c +++ b/gs/base/gsicc_cache.c @@ -66,12 +66,16 @@ static void rc_gsicc_link_cache_free(gs_memory_t * mem, void *ptr_in, client_nam /* Structure pointer information */ -gs_private_st_ptrs4(st_icc_link, gsicc_link_t, "gsiccmanage_link", - icc_link_enum_ptrs, icc_link_reloc_ptrs, +struct_proc_finalize(icc_link_finalize); + +gs_private_st_ptrs4_final(st_icc_link, gsicc_link_t, "gsiccmanage_link", + icc_link_enum_ptrs, icc_link_reloc_ptrs, icc_link_finalize, contextptr, icc_link_cache, next, wait); -gs_private_st_ptrs3(st_icc_linkcache, gsicc_link_cache_t, "gsiccmanage_linkcache", - icc_linkcache_enum_ptrs, icc_linkcache_reloc_ptrs, +struct_proc_finalize(icc_linkcache_finalize); + +gs_private_st_ptrs3_final(st_icc_linkcache, gsicc_link_cache_t, "gsiccmanage_linkcache", + icc_linkcache_enum_ptrs, icc_linkcache_reloc_ptrs, icc_linkcache_finalize, head, lock, wait); /* These are used to construct a hash for the ICC link based upon the @@ -129,12 +133,26 @@ rc_gsicc_link_cache_free(gs_memory_t * mem, void *ptr_in, client_name_t cname) } #endif gx_semaphore_free(link_cache->wait); + link_cache->wait = NULL; gx_monitor_free(link_cache->lock); + link_cache->lock = NULL; if_debug2(gs_debug_flag_icc,"[icc] Removing link cache = 0x%x memory = 0x%x\n", link_cache, link_cache->memory); gs_free_object(mem->stable_memory, link_cache, "rc_gsicc_link_cache_free"); } +/* release the semaphore and monitor of the link_cache when it is freed */ +void +icc_linkcache_finalize(const gs_memory_t *mem, void *ptr) +{ + gsicc_link_cache_t *link_cache = (gsicc_link_cache_t * ) ptr; + + gx_semaphore_free(link_cache->wait); + link_cache->wait = NULL; + gx_monitor_free(link_cache->lock); + link_cache->lock = NULL; +} + static gsicc_link_t * gsicc_alloc_link(gs_memory_t *memory, gsicc_hashlink_t hashcode) { @@ -208,9 +226,20 @@ gsicc_link_free(gsicc_link_t *icc_link, gs_memory_t *memory) { icc_link->procs.free_link(icc_link); gx_semaphore_free(icc_link->wait); + icc_link->wait = NULL; gs_free_object(memory->stable_memory, icc_link, "gsicc_link_free"); } +/* release the semaphore of the link when it is freed */ +void +icc_link_finalize(const gs_memory_t *mem, void *ptr) +{ + gsicc_link_t *icc_link = (gsicc_link_t * ) ptr; + + gx_semaphore_free(icc_link->wait); + icc_link->wait = NULL; +} + static void gsicc_mash_hash(gsicc_hashlink_t *hash) { diff --git a/gs/base/gsistate.c b/gs/base/gsistate.c index ea2b8ac09..c88012507 100644 --- a/gs/base/gsistate.c +++ b/gs/base/gsistate.c @@ -220,7 +220,8 @@ gs_imager_state_release(gs_imager_state * pis) gx_device_halftone *pdht = pis->dev_ht; #define RCDECR(element)\ - rc_decrement(pis->element, cname) + rc_decrement(pis->element, cname);\ + pis->element = NULL /* prevent subsequent decrements from this imager state */ RCDECR(cie_joint_caches); RCDECR(set_transfer.gray); diff --git a/gs/base/gsstruct.h b/gs/base/gsstruct.h index aa3f57da4..e7ab64075 100644 --- a/gs/base/gsstruct.h +++ b/gs/base/gsstruct.h @@ -306,6 +306,13 @@ struct_proc_reloc_ptrs(basic_reloc_ptrs); gs__st_basic_super(public_st, stname, stype, sname, elts, sdata, supst, supoff) #define gs_private_st_basic_super(stname, stype, sname, elts, sdata, supst, supoff)\ gs__st_basic_super(private_st, stname, stype, sname, elts, sdata, supst, supoff) + /* Basic objects with finalization and no superclass */ +#define gs__st_basic_final(scope_st, stname, stype, sname, elts, sdata, pfinal)\ + gs__st_basic_super_final(scope_st, stname, stype, sname, elts, sdata, 0, 0, pfinal) +#define gs_public_st_basic_final(stname, stype, sname, elts, sdata, pfinal)\ + gs__st_basic_final(public_st, stname, stype, sname, elts, sdata, pfinal) +#define gs_private_st_basic_final(stname, stype, sname, elts, sdata, pfinal)\ + gs__st_basic_final(private_st, stname, stype, sname, elts, sdata, pfinal) /* Basic objects with no frills. */ #define gs__st_basic(scope_st, stname, stype, sname, elts, sdata)\ gs__st_basic_super(scope_st, stname, stype, sname, elts, sdata, 0, 0) @@ -665,6 +672,7 @@ extern void reloc_const_bytestring(gs_const_bytestring *pbs, gc_state_t *gcst); /* ---------- Ordinary structures with a fixed set of pointers ----------- */ /* Note that we "cannibalize" the penum and preloc names for elts and sdata. */ +/* Both with and without finalization are defined */ /* Structures with 1 pointer. */ @@ -678,6 +686,16 @@ extern void reloc_const_bytestring(gs_const_bytestring *pbs, gc_state_t *gcst); #define gs_private_st_ptrs1(stname, stype, sname, penum, preloc, e1)\ gs__st_ptrs1(private_st, stname, stype, sname, penum, preloc, e1) +#define gs__st_ptrs1_final(scope_st, stname, stype, sname, penum, preloc, pfinal, e1)\ + BASIC_PTRS(penum) {\ + GC_OBJ_ELT(stype, e1)\ + };\ + gs__st_basic_final(scope_st, stname, stype, sname, penum, preloc, pfinal) +#define gs_public_st_ptrs1_final(stname, stype, sname, penum, preloc, pfinal, e1)\ + gs__st_ptrs1_final(public_st, stname, stype, sname, penum, preloc, pfinal, e1) +#define gs_private_st_ptrs1_final(stname, stype, sname, penum, preloc, pfinal, e1)\ + gs__st_ptrs1_final(private_st, stname, stype, sname, penum, preloc, pfinal, e1) + /* Structures with 1 string. */ #define gs__st_strings1(scope_st, stname, stype, sname, penum, preloc, e1)\ @@ -726,6 +744,16 @@ extern void reloc_const_bytestring(gs_const_bytestring *pbs, gc_state_t *gcst); #define gs_private_st_ptrs2(stname, stype, sname, penum, preloc, e1, e2)\ gs__st_ptrs2(private_st, stname, stype, sname, penum, preloc, e1, e2) +#define gs__st_ptrs2_final(scope_st, stname, stype, sname, penum, preloc, pfinal, e1, e2)\ + BASIC_PTRS(penum) {\ + GC_OBJ_ELT2(stype, e1, e2)\ + };\ + gs__st_basic_final(scope_st, stname, stype, sname, pfinal, penum, preloc) +#define gs_public_st_ptrs2_final(stname, stype, sname, penum, preloc, pfinal, e1, e2)\ + gs__st_ptrs2_final(public_st, stname, stype, sname, penum, preloc, pfinal, e1, e2) +#define gs_private_st_ptrs2_final(stname, stype, sname, penum, preloc, pfinal, e1, e2)\ + gs__st_ptrs2_final(private_st, stname, stype, sname, penum, preloc, pfinal, e1, e2) + /* Structures with 3 pointers. */ #define gs__st_ptrs3(scope_st, stname, stype, sname, penum, preloc, e1, e2, e3)\ @@ -738,6 +766,16 @@ extern void reloc_const_bytestring(gs_const_bytestring *pbs, gc_state_t *gcst); #define gs_private_st_ptrs3(stname, stype, sname, penum, preloc, e1, e2, e3)\ gs__st_ptrs3(private_st, stname, stype, sname, penum, preloc, e1, e2, e3) +#define gs__st_ptrs3_final(scope_st, stname, stype, sname, penum, preloc, pfinal, e1, e2, e3)\ + BASIC_PTRS(penum) {\ + GC_OBJ_ELT3(stype, e1, e2, e3)\ + };\ + gs__st_basic_final(scope_st, stname, stype, sname, penum, preloc, pfinal) +#define gs_public_st_ptrs3_final(stname, stype, sname, penum, preloc, pfinal, e1, e2, e3)\ + gs__st_ptrs3_final(public_st, stname, stype, sname, penum, preloc, pfinal, e1, e2, e3) +#define gs_private_st_ptrs3_final(stname, stype, sname, penum, preloc, pfinal, e1, e2, e3)\ + gs__st_ptrs3_final(private_st, stname, stype, sname, penum, preloc, pfinal, e1, e2, e3) + /* Structures with 4 pointers. */ #define gs__st_ptrs4(scope_st, stname, stype, sname, penum, preloc, e1, e2, e3, e4)\ @@ -750,6 +788,16 @@ extern void reloc_const_bytestring(gs_const_bytestring *pbs, gc_state_t *gcst); #define gs_private_st_ptrs4(stname, stype, sname, penum, preloc, e1, e2, e3, e4)\ gs__st_ptrs4(private_st, stname, stype, sname, penum, preloc, e1, e2, e3, e4) +#define gs__st_ptrs4_final(scope_st, stname, stype, sname, penum, preloc, pfinal, e1, e2, e3, e4)\ + BASIC_PTRS(penum) {\ + GC_OBJ_ELT3(stype, e1, e2, e3), GC_OBJ_ELT(stype, e4)\ + };\ + gs__st_basic_final(scope_st, stname, stype, sname, penum, preloc, pfinal) +#define gs_public_st_ptrs4_final(stname, stype, sname, penum, preloc, pfinal, e1, e2, e3, e4)\ + gs__st_ptrs4_final(public_st, stname, stype, sname, penum, preloc, pfinal, e1, e2, e3, e4) +#define gs_private_st_ptrs4_final(stname, stype, sname, penum, preloc, pfinal, e1, e2, e3, e4)\ + gs__st_ptrs4_final(private_st, stname, stype, sname, penum, preloc, pfinal, e1, e2, e3, e4) + /* Structures with 5 pointers. */ #define gs__st_ptrs5(scope_st, stname, stype, sname, penum, preloc, e1, e2, e3, e4, e5)\ @@ -762,6 +810,16 @@ extern void reloc_const_bytestring(gs_const_bytestring *pbs, gc_state_t *gcst); #define gs_private_st_ptrs5(stname, stype, sname, penum, preloc, e1, e2, e3, e4, e5)\ gs__st_ptrs5(private_st, stname, stype, sname, penum, preloc, e1, e2, e3, e4, e5) +#define gs__st_ptrs5_final(scope_st, stname, stype, sname, penum, preloc, pfinal, e1, e2, e3, e4, e5)\ + BASIC_PTRS(penum) {\ + GC_OBJ_ELT3(stype, e1, e2, e3), GC_OBJ_ELT2(stype, e4, e5)\ + };\ + gs__st_basic_final(scope_st, stname, stype, sname, penum, preloc, pfinal) +#define gs_public_st_ptrs5_final(stname, stype, sname, penum, preloc, pfinal, e1, e2, e3, e4, e5)\ + gs__st_ptrs5_final(public_st, stname, stype, sname, penum, preloc, pfinal, e1, e2, e3, e4, e5) +#define gs_private_st_ptrs5_final(stname, stype, sname, penum, preloc, pfinal, e1, e2, e3, e4, e5)\ + gs__st_ptrs5_final(private_st, stname, stype, sname, penum, preloc, pfinal, e1, e2, e3, e4, e5) + /* Structures with 6 pointers. */ #define gs__st_ptrs6(scope_st, stname, stype, sname, penum, preloc, e1, e2, e3, e4, e5, e6)\ @@ -774,6 +832,16 @@ extern void reloc_const_bytestring(gs_const_bytestring *pbs, gc_state_t *gcst); #define gs_private_st_ptrs6(stname, stype, sname, penum, preloc, e1, e2, e3, e4, e5, e6)\ gs__st_ptrs6(private_st, stname, stype, sname, penum, preloc, e1, e2, e3, e4, e5, e6) +#define gs__st_ptrs6_final(scope_st, stname, stype, sname, penum, preloc, pfinal, e1, e2, e3, e4, e5, e6)\ + BASIC_PTRS(penum) {\ + GC_OBJ_ELT3(stype, e1, e2, e3), GC_OBJ_ELT3(stype, e4, e5, e6)\ + };\ + gs__st_basic_final(scope_st, stname, stype, sname, penum, preloc, pfinal) +#define gs_public_st_ptrs6_final(stname, stype, sname, penum, preloc, pfinal, e1, e2, e3, e4, e5, e6)\ + gs__st_ptrs6_final(public_st, stname, stype, sname, penum, preloc, pfinal, e1, e2, e3, e4, e5, e6) +#define gs_private_st_ptrs6_final(stname, stype, sname, penum, preloc, pfinal, e1, e2, e3, e4, e5, e6)\ + gs__st_ptrs6_final(private_st, stname, stype, sname, penum, preloc, pfinal, e1, e2, e3, e4, e5, e6) + /* Structures with 7 pointers. */ #define gs__st_ptrs7(scope_st, stname, stype, sname, penum, preloc, e1, e2, e3, e4, e5, e6, e7)\ @@ -786,6 +854,16 @@ extern void reloc_const_bytestring(gs_const_bytestring *pbs, gc_state_t *gcst); #define gs_private_st_ptrs7(stname, stype, sname, penum, preloc, e1, e2, e3, e4, e5, e6, e7)\ gs__st_ptrs7(private_st, stname, stype, sname, penum, preloc, e1, e2, e3, e4, e5, e6, e7) +#define gs__st_ptrs7_final(scope_st, stname, stype, sname, penum, preloc, pfinal, e1, e2, e3, e4, e5, e6, e7)\ + BASIC_PTRS(penum) {\ + GC_OBJ_ELT3(stype, e1, e2, e3), GC_OBJ_ELT3(stype, e4, e5, e6), GC_OBJ_ELT(stype, e7)\ + };\ + gs__st_basic_final(scope_st, stname, stype, sname, penum, preloc, pfinal) +#define gs_public_st_ptrs7_final(stname, stype, sname, penum, preloc, pfinal, e1, e2, e3, e4, e5, e6, e7)\ + gs__st_ptrs7_final(public_st, stname, stype, sname, penum, preloc, pfinal, e1, e2, e3, e4, e5, e6, e7) +#define gs_private_st_ptrs7_final(stname, stype, sname, penum, preloc, pfinal, e1, e2, e3, e4, e5, e6, e7)\ + gs__st_ptrs7_final(private_st, stname, stype, sname, penum, preloc, pfinal, e1, e2, e3, e4, e5, e6, e7) + /* Structures with 8 pointers. */ #define gs__st_ptrs8(scope_st, stname, stype, sname, penum, preloc, e1, e2, e3, e4, e5, e6, e7, e8)\ @@ -798,6 +876,16 @@ extern void reloc_const_bytestring(gs_const_bytestring *pbs, gc_state_t *gcst); #define gs_private_st_ptrs8(stname, stype, sname, penum, preloc, e1, e2, e3, e4, e5, e6, e7, e8)\ gs__st_ptrs8(private_st, stname, stype, sname, penum, preloc, e1, e2, e3, e4, e5, e6, e7, e8) +#define gs__st_ptrs8_final(scope_st, stname, stype, sname, penum, preloc, pfinal, e1, e2, e3, e4, e5, e6, e7, e8)\ + BASIC_PTRS(penum) {\ + GC_OBJ_ELT3(stype, e1, e2, e3), GC_OBJ_ELT3(stype, e4, e5, e6), GC_OBJ_ELT2(stype, e7, e8)\ + };\ + gs__st_basic_final(scope_st, stname, stype, sname, penum, preloc, pfinal) +#define gs_public_st_ptrs8_final(stname, stype, sname, penum, preloc, pfinal, e1, e2, e3, e4, e5, e6, e7, e8)\ + gs__st_ptrs8_final(public_st, stname, stype, sname, penum, preloc, pfinal, e1, e2, e3, e4, e5, e6, e7, e8) +#define gs_private_st_ptrs8_final(stname, stype, sname, penum, preloc, pfinal, e1, e2, e3, e4, e5, e6, e7, e8)\ + gs__st_ptrs8_final(private_st, stname, stype, sname, penum, preloc, pfinal, e1, e2, e3, e4, e5, e6, e7, e8) + /* Structures with 9 pointers. */ #define gs__st_ptrs9(scope_st, stname, stype, sname, penum, preloc, e1, e2, e3, e4, e5, e6, e7, e8, e9)\ @@ -810,6 +898,16 @@ extern void reloc_const_bytestring(gs_const_bytestring *pbs, gc_state_t *gcst); #define gs_private_st_ptrs9(stname, stype, sname, penum, preloc, e1, e2, e3, e4, e5, e6, e7, e8, e9)\ gs__st_ptrs9(private_st, stname, stype, sname, penum, preloc, e1, e2, e3, e4, e5, e6, e7, e8, e9) +#define gs__st_ptrs9_final(scope_st, stname, stype, sname, penum, preloc, pfinal, e1, e2, e3, e4, e5, e6, e7, e8, e9)\ + BASIC_PTRS(penum) {\ + GC_OBJ_ELT3(stype, e1, e2, e3), GC_OBJ_ELT3(stype, e4, e5, e6), GC_OBJ_ELT3(stype, e7, e8, e9)\ + };\ + gs__st_basic_final(scope_st, stname, stype, sname, penum, preloc, pfinal) +#define gs_public_st_ptrs9_final(stname, stype, sname, penum, preloc, pfinal, e1, e2, e3, e4, e5, e6, e7, e8, e9)\ + gs__st_ptrs9_final(public_st, stname, stype, sname, penum, preloc, pfinal, e1, e2, e3, e4, e5, e6, e7, e8, e9) +#define gs_private_st_ptrs9_final(stname, stype, sname, penum, preloc, pfinal, e1, e2, e3, e4, e5, e6, e7, e8, e9)\ + gs__st_ptrs9_final(private_st, stname, stype, sname, penum, preloc, pfinal, e1, e2, e3, e4, e5, e6, e7, e8, e9) + /* Structures with 10 pointers. */ #define gs__st_ptrs10(scope_st, stname, stype, sname, penum, preloc, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10)\ @@ -822,6 +920,16 @@ extern void reloc_const_bytestring(gs_const_bytestring *pbs, gc_state_t *gcst); #define gs_private_st_ptrs10(stname, stype, sname, penum, preloc, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10)\ gs__st_ptrs10(private_st, stname, stype, sname, penum, preloc, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10) +#define gs__st_ptrs10_final(scope_st, stname, stype, sname, penum, preloc, pfinal, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10)\ + BASIC_PTRS(penum) {\ + GC_OBJ_ELT3(stype, e1, e2, e3), GC_OBJ_ELT3(stype, e4, e5, e6), GC_OBJ_ELT3(stype, e7, e8, e9),\ + GC_OBJ_ELT(stype, e10) };\ + gs__st_basic_final(scope_st, stname, stype, sname, penum, preloc, pfinal) +#define gs_public_st_ptrs10_final(stname, stype, sname, penum, preloc, pfinal, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10)\ + gs__st_ptrs10_final(public_st, stname, stype, sname, penum, preloc, pfinal, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10) +#define gs_private_st_ptrs10_final(stname, stype, sname, penum, preloc, pfinal, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10)\ + gs__st_ptrs10_final(private_st, stname, stype, sname, penum, preloc, pfinal, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10) + /* Structures with 11 pointers. */ #define gs__st_ptrs11(scope_st, stname, stype, sname, penum, preloc, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11)\ @@ -834,6 +942,16 @@ extern void reloc_const_bytestring(gs_const_bytestring *pbs, gc_state_t *gcst); #define gs_private_st_ptrs11(stname, stype, sname, penum, preloc, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11)\ gs__st_ptrs11(private_st, stname, stype, sname, penum, preloc, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11) +#define gs__st_ptrs11_final(scope_st, stname, stype, sname, penum, preloc, pfinal, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11)\ + BASIC_PTRS(penum) {\ + GC_OBJ_ELT3(stype, e1, e2, e3), GC_OBJ_ELT3(stype, e4, e5, e6), GC_OBJ_ELT3(stype, e7, e8, e9),\ + GC_OBJ_ELT2(stype, e10, e11) };\ + gs__st_basic_final(scope_st, stname, stype, sname, penum, preloc, pfinal) +#define gs_public_st_ptrs11_final(stname, stype, sname, penum, preloc, pfinal, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11)\ + gs__st_ptrs11_final(public_st, stname, stype, sname, penum, preloc, pfinal, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11) +#define gs_private_st_ptrs11_final(stname, stype, sname, penum, preloc, pfinal, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11)\ + gs__st_ptrs11_final(private_st, stname, stype, sname, penum, preloc, pfinal, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11) + /* Structures with 1 const string and 1 pointer. */ #define gs__st_const_strings1_ptrs1(scope_st, stname, stype, sname, penum, preloc, e1, e2)\ |