2 * collection.c: Garbage collection for handles
5 * Dick Porter (dick@ximian.com)
7 * (C) 2004 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>
23 static pthread_t collection_thread_id;
25 static gpointer collection_thread (gpointer args) G_GNUC_NORETURN;
26 static gpointer collection_thread (gpointer unused G_GNUC_UNUSED)
28 struct timespec sleepytime;
30 sleepytime.tv_sec = 10;
31 sleepytime.tv_nsec = 0;
34 //_wapi_handle_dump ();
35 _wapi_handle_update_refs ();
36 nanosleep (&sleepytime, NULL);
40 void _wapi_collection_init (void)
45 ret = pthread_attr_init (&attr);
48 #ifdef HAVE_PTHREAD_ATTR_SETSTACKSIZE
49 ret = pthread_attr_setstacksize (&attr, PTHREAD_STACK_MIN);
53 ret = pthread_create (&collection_thread_id, &attr, collection_thread,
56 g_error ("%s: Couldn't create handle collection thread: %s",
57 __func__, g_strerror (ret));
61 void _wapi_handle_collect (void)
63 guint32 count = _wapi_shared_layout->collection_count;
67 g_message ("%s: (%d) Starting a collection", __func__, getpid ());
70 /* Become the collection master */
71 _WAPI_HANDLE_COLLECTION_UNSAFE;
74 g_message ("%s: (%d) Master set", __func__, getpid ());
77 /* If count has changed, someone else jumped in as master */
78 if (count == _wapi_shared_layout->collection_count) {
79 for (i = 0; i < _WAPI_HANDLE_INITIAL_COUNT; i++) {
80 struct _WapiHandleShared *shared;
81 struct _WapiHandleSharedMetadata *meta;
82 guint32 too_old = (guint32)(time(NULL) & 0xFFFFFFFF) - 300; /* 5 minutes without update */
84 meta = &_wapi_shared_layout->metadata[i];
85 if (meta->timestamp < too_old && meta->offset != 0) {
87 g_message ("%s: (%d) Deleting metadata slot 0x%x handle 0x%x", __func__, getpid (), i, meta->offset);
89 memset (&_wapi_shared_layout->handles[meta->offset], '\0', sizeof(struct _WapiHandleShared));
90 memset (&_wapi_shared_layout->metadata[i], '\0', sizeof(struct _WapiHandleSharedMetadata));
93 /* Need to blank any handles data that is no
94 * longer pointed to by a metadata entry too
96 shared = &_wapi_shared_layout->handles[i];
97 if (shared->stale == TRUE) {
99 g_message ("%s: (%d) Deleting stale handle 0x%x", __func__, getpid (), i);
101 memset (&_wapi_shared_layout->handles[i], '\0',
102 sizeof(struct _WapiHandleShared));
106 for (i = 0; i < _wapi_fileshare_layout->hwm; i++) {
107 struct _WapiFileShare *file_share = &_wapi_fileshare_layout->share_info[i];
108 guint32 too_old = (guint32)(time(NULL) & 0xFFFFFFFF) - 300; /* 5 minutes without update */
110 if (file_share->timestamp < too_old) {
111 memset (file_share, '\0',
112 sizeof(struct _WapiFileShare));
116 InterlockedIncrement (&_wapi_shared_layout->collection_count);
119 _WAPI_HANDLE_COLLECTION_SAFE;
122 g_message ("%s: (%d) Collection done", __func__, getpid ());