2 * collection.c: Garbage collection for handles
5 * Dick Porter (dick@ximian.com)
7 * (C) 2004-2006 Novell, Inc.
14 #include <sys/types.h>
17 #include <mono/io-layer/wapi.h>
18 #include <mono/io-layer/collection.h>
19 #include <mono/io-layer/handles-private.h>
20 #include <mono/utils/atomic.h>
23 // #define DEBUG(...) g_message(__VA_ARGS__)
28 static pthread_t collection_thread_id;
30 static gpointer collection_thread (gpointer unused G_GNUC_UNUSED)
32 struct timespec sleepytime;
34 sleepytime.tv_sec = _WAPI_HANDLE_COLLECTION_UPDATE_INTERVAL;
35 sleepytime.tv_nsec = 0;
37 while (_wapi_has_shut_down == FALSE) {
38 nanosleep (&sleepytime, NULL);
40 //_wapi_handle_dump ();
41 _wapi_handle_update_refs ();
49 void _wapi_collection_init (void)
53 int set_stacksize = 0;
56 ret = pthread_attr_init (&attr);
59 #if defined(HAVE_PTHREAD_ATTR_SETSTACKSIZE)
60 if (set_stacksize == 0) {
61 ret = pthread_attr_setstacksize (&attr, MAX (65536, PTHREAD_STACK_MIN));
63 } else if (set_stacksize == 1) {
64 ret = pthread_attr_setstacksize (&attr, 131072);
69 ret = pthread_create (&collection_thread_id, &attr, collection_thread,
71 if (ret != 0 && set_stacksize < 2) {
76 g_error ("%s: Couldn't create handle collection thread: %s",
77 __func__, g_strerror (ret));
81 void _wapi_handle_collect (void)
83 guint32 count = _wapi_shared_layout->collection_count;
86 if (!_wapi_shm_enabled ())
89 DEBUG ("%s: (%d) Starting a collection", __func__, _wapi_getpid ());
91 /* Become the collection master */
92 thr_ret = _wapi_handle_lock_shared_handles ();
93 g_assert (thr_ret == 0);
95 thr_ret = _wapi_shm_sem_lock (_WAPI_SHARED_SEM_FILESHARE);
96 g_assert (thr_ret == 0);
98 DEBUG ("%s: (%d) Master set", __func__, _wapi_getpid ());
100 /* If count has changed, someone else jumped in as master */
101 if (count == _wapi_shared_layout->collection_count) {
102 guint32 too_old = (guint32)(time(NULL) & 0xFFFFFFFF) - _WAPI_HANDLE_COLLECTION_EXPIRED_INTERVAL;
104 for (i = 0; i < _WAPI_HANDLE_INITIAL_COUNT; i++) {
105 struct _WapiHandleShared *data;
107 data = &_wapi_shared_layout->handles[i];
108 if (data->timestamp < too_old) {
109 DEBUG ("%s: (%d) Deleting handle 0x%x", __func__, _wapi_getpid (), i);
110 memset (&_wapi_shared_layout->handles[i], '\0', sizeof(struct _WapiHandleShared));
114 for (i = 0; i < _wapi_fileshare_layout->hwm; i++) {
115 struct _WapiFileShare *file_share = &_wapi_fileshare_layout->share_info[i];
117 if (file_share->timestamp < too_old) {
118 memset (file_share, '\0',
119 sizeof(struct _WapiFileShare));
123 InterlockedIncrement ((gint32 *)&_wapi_shared_layout->collection_count);
126 thr_ret = _wapi_shm_sem_unlock (_WAPI_SHARED_SEM_FILESHARE);
127 g_assert (thr_ret == 0);
129 _wapi_handle_unlock_shared_handles ();
131 DEBUG ("%s: (%d) Collection done", __func__, _wapi_getpid ());