From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 3765 invoked by alias); 26 Sep 2006 08:41:17 -0000 Received: (qmail 3752 invoked by uid 22791); 26 Sep 2006 08:41:15 -0000 X-Spam-Check-By: sourceware.org Received: from viper.snap.net.nz (HELO viper.snap.net.nz) (202.37.101.8) by sourceware.org (qpsmtpd/0.31) with ESMTP; Tue, 26 Sep 2006 08:41:12 +0000 Received: from kahikatea.snap.net.nz (p202-124-120-79.snap.net.nz [202.124.120.79]) by viper.snap.net.nz (Postfix) with ESMTP id 5A8467B8F5E; Tue, 26 Sep 2006 20:41:08 +1200 (NZST) Received: by kahikatea.snap.net.nz (Postfix, from userid 500) id F2339BE436; Tue, 26 Sep 2006 20:38:24 +1200 (NZST) From: Nick Roberts MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit Message-ID: <17688.59135.24869.397517@kahikatea.snap.net.nz> Date: Tue, 26 Sep 2006 08:41:00 -0000 To: Daniel Jacobowitz Cc: gdb@sources.redhat.com Subject: Re: Merge of nickrob-async-20060513 to mainline? In-Reply-To: <20060830214257.GA5397@nevyn.them.org> References: <17652.63229.637451.185345@kahikatea.snap.net.nz> <20060830023335.GA6377@nevyn.them.org> <17653.930.196634.143646@kahikatea.snap.net.nz> <20060830040113.GA8257@nevyn.them.org> <17654.994.815362.897653@kahikatea.snap.net.nz> <20060830214257.GA5397@nevyn.them.org> X-Mailer: VM 7.19 under Emacs 22.0.50.20 X-IsSubscribed: yes Mailing-List: contact gdb-help@sourceware.org; run by ezmlm Precedence: bulk List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-owner@sourceware.org X-SW-Source: 2006-09/txt/msg00148.txt.bz2 > > Instead of GDB waiting for the enferior to stop directly, it creates a > > signal thread to do that. This means that the main thread can continue to > > process the event loop. When the inferior does stop, the signal thread > > writes to a file which GDB detects through handle_file_event in the event > > loop. It then calls inferior_event_handler. > > OK, this is easily mimicable without threads, at least on GNU/Linux. I'm starting to do this now. I still use a pipe to write to a file descriptor but instead of a separate thread I use a while loop in gdb_wait_for_event. I've only done it for select because that's all I know but I guess a similar thing could be done for poll. It seems to work reasonably well for single threaded inferiors but get's stuck again with multi-threaded ones. The multi-threaded code in linux-nat.c just seems so convoluted (maybe threads are more easily handled with a Mach kernel). Below is a (pseudo) diff fragment that should (hopefully) give the general idea. Do you mean something along these lines? If yes, I'll try to get it to work more generally. -- Nick http://www.inet.net.nz/~nickrob *** linux-nat.c 18 Sep 2006 16:44:40 +1200 1.50 + static int gdb_fetch_event (int* ptr_status) + { + struct timeval tv; + fd_set fds; + int msg[2], ret; + + FD_ZERO (&fds); + FD_SET (gdb_status[0], &fds); + tv.tv_sec = 0; + tv.tv_usec = 0; + + msg[0] = 0; + ret = select (FD_SETSIZE, &fds, NULL, NULL, NULL); + if (ret) + { + read (gdb_status[0], msg, 2*sizeof (int)); + *ptr_status = msg[1]; + } + + return msg[0]; + } + static ptid_t linux_nat_wait (ptid_t ptid, struct target_waitstatus *ourstatus) { *************** *** 1956,1962 **** (linux_nat_wait) { pid_t lwpid; ! lwpid = my_waitpid (pid, &status, options); if (lwpid > 0) { gdb_assert (pid == -1 || lwpid == pid); --- 2094,2106 ---- { pid_t lwpid; ! if (target_can_async_p () && gdb_post_startup) ! { ! gdb_file_event = 0; ! lwpid = gdb_fetch_event (&status); ! } ! else ! lwpid = my_waitpid (pid, &status, options); if (lwpid > 0) { gdb_assert (pid == -1 || lwpid == pid); *** event-loop.c (gdb_wait_for_event) 11 Feb 2006 11:01:43 +1300 1.29 gdb_notifier.ready_masks[0] = gdb_notifier.check_masks[0]; gdb_notifier.ready_masks[1] = gdb_notifier.check_masks[1]; gdb_notifier.ready_masks[2] = gdb_notifier.check_masks[2]; ! num_found = gdb_select (gdb_notifier.num_fds, ! &gdb_notifier.ready_masks[0], ! &gdb_notifier.ready_masks[1], ! &gdb_notifier.ready_masks[2], ! gdb_notifier.timeout_valid ! ? &gdb_notifier.select_timeout : NULL); /* Clear the masks after an error from select. */ if (num_found == -1) --- 765,806 ---- gdb_notifier.ready_masks[0] = gdb_notifier.check_masks[0]; gdb_notifier.ready_masks[1] = gdb_notifier.check_masks[1]; gdb_notifier.ready_masks[2] = gdb_notifier.check_masks[2]; ! ! if (event_loop_p) ! { ! struct timeval tv; ! ! while (num_found == 0) ! { ! msg[0] = waitpid (-1, ptr_status, WNOHANG); ! ! if (msg[0] > 0) ! { ! msg[1] = *ptr_status; ! write (gdb_status[1], msg, 2*sizeof (int)); ! gdb_file_event = 1; ! } ! ! tv.tv_sec = 0; ! tv.tv_usec = 1000; ! ! gdb_notifier.ready_masks[0] = gdb_notifier.check_masks[0]; ! gdb_notifier.ready_masks[1] = gdb_notifier.check_masks[1]; ! gdb_notifier.ready_masks[2] = gdb_notifier.check_masks[2]; ! ! num_found = gdb_select (gdb_notifier.num_fds, ! &gdb_notifier.ready_masks[0], ! &gdb_notifier.ready_masks[1], ! &gdb_notifier.ready_masks[2], ! &tv); ! } ! } else ! num_found = gdb_select (gdb_notifier.num_fds, ! &gdb_notifier.ready_masks[0], ! &gdb_notifier.ready_masks[1], ! &gdb_notifier.ready_masks[2], ! gdb_notifier.timeout_valid ! ? &gdb_notifier.select_timeout : NULL);