static ThreadPool* threadpool;
-#define COUNTER_CHECK(counter) \
- do { \
- g_assert (sizeof (ThreadPoolCounter) == sizeof (gint32)); \
- g_assert (counter._.starting >= 0); \
- g_assert (counter._.working >= 0); \
- } while (0)
-
#define COUNTER_ATOMIC(threadpool,var,block) \
do { \
ThreadPoolCounter __old; \
do { \
g_assert (threadpool); \
- __old = COUNTER_READ (threadpool); \
- (var) = __old; \
+ (var) = __old = COUNTER_READ (threadpool); \
{ block; } \
- COUNTER_CHECK (var); \
+ if (!(counter._.starting >= 0)) \
+ g_error ("%s: counter._.starting = %d, but should be >= 0", __func__, counter._.starting); \
+ if (!(counter._.working >= 0)) \
+ g_error ("%s: counter._.working = %d, but should be >= 0", __func__, counter._.working); \
} while (InterlockedCompareExchange (&threadpool->counters.as_gint32, (var).as_gint32, __old.as_gint32) != __old.as_gint32); \
} while (0)
threadpool = g_new0 (ThreadPool, 1);
g_assert (threadpool);
+ g_assert (sizeof (ThreadPoolCounter) == sizeof (gint32));
+
mono_refcount_init (threadpool, destroy);
threadpool->domains = g_ptr_array_new ();
mono_coop_mutex_lock (&threadpool->threads_lock);
for (;;) {
- ThreadPoolCounter counter;
-
- counter = COUNTER_READ (threadpool);
- if (counter._.working == 0)
+ if (threadpool->threads->len == 0)
break;
- if (counter._.working == 1) {
- if (threadpool->threads->len == 1 && g_ptr_array_index (threadpool->threads, 0) == current) {
- /* We are waiting on ourselves */
- break;
- }
+ if (threadpool->threads->len == 1 && g_ptr_array_index (threadpool->threads, 0) == current) {
+ /* We are waiting on ourselves */
+ break;
}
mono_coop_cond_wait (&threadpool->threads_exit_cond, &threadpool->threads_lock);
thread = mono_thread_internal_current ();
COUNTER_ATOMIC (threadpool, counter, {
+ if (!(counter._.working < 32767 /* G_MAXINT16 */))
+ g_error ("%s: counter._.working = %d, but should be < 32767", __func__, counter._.working);
+
counter._.starting --;
counter._.working ++;
});
mono_coop_mutex_lock (&threadpool->threads_lock);
- COUNTER_ATOMIC (threadpool, counter, {
- counter._.working --;
- });
-
g_ptr_array_remove_fast (threadpool->threads, thread);
mono_coop_cond_signal (&threadpool->threads_exit_cond);
mono_coop_mutex_unlock (&threadpool->threads_lock);
+ COUNTER_ATOMIC (threadpool, counter, {
+ counter._.working --;
+ });
+
mono_refcount_dec (threadpool);
}
* The is_unloading () check in worker_request () ensures that
* no new jobs are added after we enter the lock below.
*/
- mono_lazy_initialize (&status, initialize);
+
+ if (!mono_lazy_is_initialized (&status))
+ return TRUE;
+
+ mono_refcount_inc (threadpool);
+
domains_lock ();
tpdomain = tpdomain_get (domain, FALSE);
if (!tpdomain) {
domains_unlock ();
+ mono_refcount_dec (threadpool);
return TRUE;
}
mono_coop_cond_destroy (&tpdomain->cleanup_cond);
tpdomain_free (tpdomain);
+ mono_refcount_dec (threadpool);
+
return ret;
}
mono_refcount_inc (threadpool);
COUNTER_ATOMIC (threadpool, counter, {
+ if (!(counter._.starting < 32767 /* G_MAXINT16 */))
+ g_error ("%s: counter._.starting = %d, but should be < 32767", __func__, counter._.starting);
+
counter._.starting ++;
});