From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: Eli Zaretskii Newsgroups: gmane.emacs.devel Subject: Re: Dynamic loading progress Date: Sat, 21 Nov 2015 10:35:31 +0200 Message-ID: <83wptb4ung.fsf@gnu.org> References: <83k2ptq5t3.fsf@gnu.org> <87h9kxx60e.fsf@lifelogs.com> <877flswse5.fsf@lifelogs.com> <8737wgw7kf.fsf@lifelogs.com> <87io5bv1it.fsf@lifelogs.com> <87egfzuwca.fsf@lifelogs.com> <876118u6f2.fsf@lifelogs.com> <8737w3qero.fsf@lifelogs.com> <831tbn9g9j.fsf@gnu.org> <878u5upw7o.fsf@lifelogs.com> <83ziya8xph.fsf@gnu.org> <83y4du80xo.fsf@gnu.org> <837fld6lps.fsf@gnu.org> <83610w5o97.fsf@gnu.org> Reply-To: Eli Zaretskii NNTP-Posting-Host: plane.gmane.org X-Trace: ger.gmane.org 1448094974 22169 80.91.229.3 (21 Nov 2015 08:36:14 GMT) X-Complaints-To: usenet@ger.gmane.org NNTP-Posting-Date: Sat, 21 Nov 2015 08:36:14 +0000 (UTC) Cc: aurelien.aptel+emacs@gmail.com, tzz@lifelogs.com, emacs-devel@gnu.org To: Philipp Stephani Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Sat Nov 21 09:35:56 2015 Return-path: Envelope-to: ged-emacs-devel@m.gmane.org Original-Received: from lists.gnu.org ([208.118.235.17]) by plane.gmane.org with esmtp (Exim 4.69) (envelope-from ) id 1a03eF-0003Fp-Ma for ged-emacs-devel@m.gmane.org; Sat, 21 Nov 2015 09:35:55 +0100 Original-Received: from localhost ([::1]:51494 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1a03eF-0005M8-2J for ged-emacs-devel@m.gmane.org; Sat, 21 Nov 2015 03:35:55 -0500 Original-Received: from eggs.gnu.org ([2001:4830:134:3::10]:44989) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1a03e8-0005LW-VR for emacs-devel@gnu.org; Sat, 21 Nov 2015 03:35:50 -0500 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1a03e4-0005CK-T1 for emacs-devel@gnu.org; Sat, 21 Nov 2015 03:35:48 -0500 Original-Received: from mtaout20.012.net.il ([80.179.55.166]:45336) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1a03e4-0005Bp-BC for emacs-devel@gnu.org; Sat, 21 Nov 2015 03:35:44 -0500 Original-Received: from conversion-daemon.a-mtaout20.012.net.il by a-mtaout20.012.net.il (HyperSendmail v2007.08) id <0NY500200ON3OY00@a-mtaout20.012.net.il> for emacs-devel@gnu.org; Sat, 21 Nov 2015 10:35:42 +0200 (IST) Original-Received: from HOME-C4E4A596F7 ([84.94.185.246]) by a-mtaout20.012.net.il (HyperSendmail v2007.08) with ESMTPA id <0NY50029SP7IGU90@a-mtaout20.012.net.il>; Sat, 21 Nov 2015 10:35:42 +0200 (IST) In-reply-to: X-012-Sender: halo1@inter.net.il X-detected-operating-system: by eggs.gnu.org: Solaris 10 X-Received-From: 80.179.55.166 X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: "Emacs development discussions." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Original-Sender: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Xref: news.gmane.org gmane.emacs.devel:194925 Archived-At: > From: Philipp Stephani > Date: Fri, 20 Nov 2015 23:22:49 +0000 > Cc: tzz@lifelogs.com, aurelien.aptel+emacs@gmail.com, emacs-devel@gnu.org > > Ah, you are talking about C++ dynamic initializers! So the model is > that someone writes a module in C++, starts a thread there, and then > inside some dynamic initializer calls emacs-module interface > functions, is that it? If that's the situation, I'd suggest a > prominent commentary describing this in the source. > > The SO post talks about C++ but the issue is the same in C. AFAIK with C11 and > C++11 the execution models are harmonized. It doesn't matter for the issue at hand whether it's C, C++, Java, or whatever. My originally incorrect interpretation of what you wrote was that you are talking about initializers that are part of the module code, i.e. the emacs_module_init function they implement. > It seems the comment is overly confusing. It is supposed to warn about the > following. Naively, if you wanted to test whether you are in the main thread, > you would do (module types and naming): > > static thread_id main_thread = get_current_thread(); > bool in_main_thread() { return get_current_thread() == main_thread; } > > The dynamic initializer here is the first "get_current_thread()"; it is not > guaranteed to run in the main thread, so "main_thread" is not guaranteed to > contain the main thread ID. Therefore you have to do: > > static thread_id main_thread; // initialized later > int main() { > // guaranteed to be in the main thread > main_thread = get_current_thread(); > } > > That's all. I'm not aware of any runtime that would run dynamic initializers > outside of the main thread, but it's not impossible and easy to protect > against. AFAIK, code that does this: static thread_id main_thread = get_current_thread(); is invalid in C, because such initializers cannot call functions. So it would surprise me to see code which tried to record its thread ID before 'main'. So I think we should reword that comment to be much less mysterious and confusing than it is now. (Look how much did we need to talk about for you to explain to me what was the intent of the comment.) > Anyway, thanks for explaining this, I now know how to change the code > to DTRT on MS-Windows wrt to the thread checks. > > This is unfortunately all surprisingly subtle and vaguely defined. See e.g. > http://stackoverflow.com/q/19744250/178761 (apparently the standards are vague > about what happens to detached threads after main has exited). I don't see how that affects the issue at hand. The issue at hand is whether a thread ID of the main thread could be reused while some of the other threads belonging to the Emacs process are still running. And the answer to that on MS-Windows is AFAIU a sound NO, because as long as the Emacs process is alive, it holds a handle on the main thread, which precludes the OS from discarding that thread's kernel object. Why? because a thread handle can and is used to query the OS about that thread's conditions, like its exit code, or wait for its completion in the likes of WaitForSingleObject. So the kernel object that represents the thread must be kept by the OS as long as at least one open handle for the thread exists, and that prevents the OS from reusing the thread ID. > > See also > > http://blogs.msdn.com/b/oldnewthing/archive/2006/09/27/773741.aspx. > > We don't use IsBadWritePtr on Windows to check this, see > w32_valid_pointer_p for how this is actually implemented. > > Much of this applies generally. > > "But what should I do, then, if somebody passes me a bad pointer?" > > You should crash. Which is what we do, since eassert aborts. We will just do it sooner, which IME is a Good Thing. > Anyway, I'm surprised by this extreme POV: even if we cannot validate > a pointer 100%, surely it doesn't mean we cannot or shouldn't do some > partial job? Why this "all or nothing" approach? > > We can check whether it's NULL. Apart from that, everything else is outside of > the C standard. Emacs is not a Standard C program, far from it. It uses a lot of stuff outside of any C standard, and for a very good reason: it is a large and complicate program with many features that require access to OS facilities. IOW, using only Standard C features is not, and cannot be, a requirement for Emacs code. > We need to devise a way for it to detect that it was called from > emacs-module.c, the rest is simple, I think. > > Hmm, why does it need to detect anything? Can't it just be a different function > that doesn't signal, similar to push_handler and push_handler_nosignal? I don't think we want each of its callers call the signaling part by itself. That would be repeating the problem with malloc itself: many programs simply neglect to include the code which does TRT when it returns NULL. xmalloc solves this, and makes sure the (non-trivial) error action and message are always the same in that case. We need a variant of this for memory allocated on behalf of modules, I think.