From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 3976 invoked by alias); 5 Dec 2006 23:12:20 -0000 Received: (qmail 3965 invoked by uid 22791); 5 Dec 2006 23:12:18 -0000 X-Spam-Check-By: sourceware.org Received: from cv3.cv.nrao.edu (HELO cv3.cv.nrao.edu) (192.33.115.2) by sourceware.org (qpsmtpd/0.31) with ESMTP; Tue, 05 Dec 2006 23:12:10 +0000 Received: from [127.0.0.1] (rpm.ad.nrao.edu [10.12.96.162]) by cv3.cv.nrao.edu (8.13.1/8.13.1/cv-ws-8.12) with ESMTP id kB5NC4M3003109 for ; Tue, 5 Dec 2006 18:12:04 -0500 Message-ID: <4575FCC4.5020707@nrao.edu> Date: Tue, 05 Dec 2006 23:12:00 -0000 From: Morgan McLeod User-Agent: Mozilla Thunderbird 1.0.6 (Windows/20050716) MIME-Version: 1.0 To: pthreads-win32@sources.redhat.com Subject: Re: semaphores and handle leaks References: <456C62A1.9090202@marcelruff.info> <456C63DC.4010008@marcelruff.info> <456D6AEC.8070804@marcelruff.info> <4575E103.8080105@nrao.edu> In-Reply-To: <4575E103.8080105@nrao.edu> Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit X-MailScanner-Information: Please contact postmaster@cv.nrao.edu for more information X-MailScanner: Found to be clean X-MailScanner-SpamCheck: not spam, SpamAssassin (not cached, score=-101.44, required 5, autolearn=disabled, ALL_TRUSTED -1.44, USER_IN_WHITELIST -100.00) X-IsSubscribed: yes Mailing-List: contact pthreads-win32-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: pthreads-win32-owner@sourceware.org X-SW-Source: 2006/txt/msg00068.txt.bz2 Hello again. Below is C++ code for a fairly simple program which exhibits the apparent handle leaks I described in my previous posting. I linked this with the standard STL rather than STLPort and it makes no difference. This is compiled to an EXE, not a DLL like my real application. Again, please feel free to point out if I'm doing somethign wrong. Thanks -Morgan McLeod Software Engineer National Radio Astronomy Observatory Charlottesville, Va #include #include #include #include #include struct listElem { int num; sem_t *synchLock; listElem(int _num, sem_t *_synchLock) : num(_num), synchLock(_synchLock) {} ~listElem() {} }; typedef std::list semList_t; semList_t list1; semList_t list2; // mutexes to protect the lists: pthread_mutex_t mutex1; pthread_mutex_t mutex2; // flags to tell the threads to stop: bool shutdownNow; bool shutdownDone1; bool shutdownDone2; // thread 1 processes list1: void *thread1(void *arg) { while (true) { if (shutdownNow) { shutdownDone1 = true; pthread_exit(NULL); } pthread_mutex_lock(&mutex1); if (list1.empty()) pthread_mutex_unlock(&mutex1); else { // remove the front element from the list: listElem E = list1.front(); list1.pop_front(); pthread_mutex_unlock(&mutex1); // save the original semaphore: sem_t *sem1 = E.synchLock; // create and initialize a new semaphore. // substitute it for the original: sem_t sem2; E.synchLock = &sem2; sem_init(E.synchLock, 0, 0); // put the item in list2 for processing by thread2: pthread_mutex_lock(&mutex2); list2.push_back(E); pthread_mutex_unlock(&mutex2); // Wait on, then destroy the substitute semaphore: sem_wait(E.synchLock); sem_destroy(E.synchLock); // put back and post on the original semaphore: E.synchLock = sem1; sem_post(E.synchLock); printf("thread1: %d done\n", E.num); } Sleep(10); } } // thread2 processes list2: void *thread2(void *arg) { while (true) { if (shutdownNow) { shutdownDone2 = true; pthread_exit(NULL); } pthread_mutex_lock(&mutex2); if (list2.empty()) pthread_mutex_unlock(&mutex2); else { listElem E = list2.front(); list2.pop_front(); pthread_mutex_unlock(&mutex2); sem_post(E.synchLock); printf("thread2: %d done\n", E.num); } Sleep(10); } } const int COUNT = 1000; int main(int, char*[]) { // Initialize flags: shutdownNow = shutdownDone1 = shutdownDone2 = false; // Pause to look at Task Manager. Handles = 8: Sleep(5000); pthread_mutex_init(&mutex1, NULL); pthread_mutex_init(&mutex2, NULL); sem_t synchLocks[COUNT]; for (int index = 0; index < COUNT; ++index) { sem_init(&synchLocks[index], 0, 0); listElem E(index, &synchLocks[index]); list1.push_back(E); } // Handles = 2019. Starts to leak... pthread_t T1; pthread_create(&T1, NULL, thread1, NULL); pthread_t T2; pthread_create(&T2, NULL, thread2, NULL); while (!list1.empty() || !list2.empty()) Sleep(10); // Pause to look at Task Manager. Handles = 2261 (varies): Sleep(5000); shutdownNow = true; while (!shutdownDone1 && !shutdownDone2) Sleep(10); for (int index = 0; index < COUNT; ++index) sem_destroy(&synchLocks[index]); pthread_mutex_destroy(&mutex1); pthread_mutex_destroy(&mutex2); // Pause to look at Task Manager. Handles = 264 (varies): Sleep(5000); printf("done\n"); return 0; }