gc_dlopen.c 3.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. /*
  2. * Copyright (c) 1991-1994 by Xerox Corporation. All rights reserved.
  3. * Copyright (c) 1997 by Silicon Graphics. All rights reserved.
  4. * Copyright (c) 2000 by Hewlett-Packard Company. All rights reserved.
  5. *
  6. * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED
  7. * OR IMPLIED. ANY USE IS AT YOUR OWN RISK.
  8. *
  9. * Permission is hereby granted to use or copy this program
  10. * for any purpose, provided the above notices are retained on all copies.
  11. * Permission to modify the code and to distribute modified code is granted,
  12. * provided the above notices are retained, and a notice that the code was
  13. * modified is included with the above copyright notice.
  14. *
  15. * Original author: Bill Janssen
  16. * Heavily modified by Hans Boehm and others
  17. */
  18. /*
  19. * This used to be in dyn_load.c. It was extracted into a separate file
  20. * to avoid having to link against libdl.{a,so} if the client doesn't call
  21. * dlopen. Of course this fails if the collector is in a dynamic
  22. * library. -HB
  23. */
  24. #include "private/gc_priv.h"
  25. # if (defined(GC_PTHREADS) && !defined(GC_DARWIN_THREADS)) \
  26. || defined(GC_SOLARIS_THREADS)
  27. # if defined(dlopen) && !defined(GC_USE_LD_WRAP)
  28. /* To support various threads pkgs, gc.h interposes on dlopen by */
  29. /* defining "dlopen" to be "GC_dlopen", which is implemented below. */
  30. /* However, both GC_FirstDLOpenedLinkMap() and GC_dlopen() use the */
  31. /* real system dlopen() in their implementation. We first remove */
  32. /* gc.h's dlopen definition and restore it later, after GC_dlopen(). */
  33. # undef dlopen
  34. # endif
  35. /* Make sure we're not in the middle of a collection, and make */
  36. /* sure we don't start any. Returns previous value of GC_dont_gc. */
  37. /* This is invoked prior to a dlopen call to avoid synchronization */
  38. /* issues. We can't just acquire the allocation lock, since startup */
  39. /* code in dlopen may try to allocate. */
  40. /* This solution risks heap growth in the presence of many dlopen */
  41. /* calls in either a multithreaded environment, or if the library */
  42. /* initialization code allocates substantial amounts of GC'ed memory. */
  43. /* But I don't know of a better solution. */
  44. static void disable_gc_for_dlopen()
  45. {
  46. LOCK();
  47. while (GC_incremental && GC_collection_in_progress()) {
  48. GC_collect_a_little_inner(1000);
  49. }
  50. ++GC_dont_gc;
  51. UNLOCK();
  52. }
  53. /* Redefine dlopen to guarantee mutual exclusion with */
  54. /* GC_register_dynamic_libraries. */
  55. /* Should probably happen for other operating systems, too. */
  56. #include <dlfcn.h>
  57. #ifdef GC_USE_LD_WRAP
  58. void * __wrap_dlopen(const char *path, int mode)
  59. #else
  60. void * GC_dlopen(path, mode)
  61. GC_CONST char * path;
  62. int mode;
  63. #endif
  64. {
  65. void * result;
  66. # ifndef USE_PROC_FOR_LIBRARIES
  67. disable_gc_for_dlopen();
  68. # endif
  69. # ifdef GC_USE_LD_WRAP
  70. result = (void *)__real_dlopen(path, mode);
  71. # else
  72. result = dlopen(path, mode);
  73. # endif
  74. # ifndef USE_PROC_FOR_LIBRARIES
  75. GC_enable(); /* undoes disable_gc_for_dlopen */
  76. # endif
  77. return(result);
  78. }
  79. # endif /* GC_PTHREADS || GC_SOLARIS_THREADS ... */