Return-Path: X-Original-To: apmail-apr-dev-archive@www.apache.org Delivered-To: apmail-apr-dev-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 7EC4C102F0 for ; Sun, 22 Sep 2013 03:59:41 +0000 (UTC) Received: (qmail 23435 invoked by uid 500); 22 Sep 2013 03:59:33 -0000 Delivered-To: apmail-apr-dev-archive@apr.apache.org Received: (qmail 23375 invoked by uid 500); 22 Sep 2013 03:59:29 -0000 Mailing-List: contact dev-help@apr.apache.org; run by ezmlm Precedence: bulk List-Post: List-Help: List-Unsubscribe: List-Id: Delivered-To: mailing list dev@apr.apache.org Received: (qmail 23367 invoked by uid 99); 22 Sep 2013 03:59:25 -0000 Received: from minotaur.apache.org (HELO minotaur.apache.org) (140.211.11.9) by apache.org (qpsmtpd/0.29) with ESMTP; Sun, 22 Sep 2013 03:59:25 +0000 Received: from localhost (HELO zulu.local) (127.0.0.1) (smtp-auth username brane, mechanism plain) by minotaur.apache.org (qpsmtpd/0.29) with ESMTP; Sun, 22 Sep 2013 03:59:24 +0000 Message-ID: <523E6B1A.2060506@apache.org> Date: Sun, 22 Sep 2013 05:59:22 +0200 From: =?UTF-8?B?QnJhbmtvIMSMaWJlag==?= User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.8; rv:17.0) Gecko/20130801 Thunderbird/17.0.8 MIME-Version: 1.0 To: dev@apr.apache.org Subject: Re: thread safety of apr_initialize References: In-Reply-To: X-Enigmail-Version: 1.5.2 Face: iVBORw0KGgoAAAANSUhEUgAAADAAAAAwBAMAAAClLOS0AAAAAXNSR0IArs4c6QAAADBQTFRF IhsbCy0qZjoVOVRoeFxSAIKBzXQiAKaibYiewnk7nn9z0qCTgL3i87Ep6Kx/+tHBsrE+zgAAAjZJ REFUOMvF0jFoE1EYB/CzjWlqIzaTjqVIBifRRWyG0t5iUqlLyFpCeXBgKg5yq6A4degUDJjoUDpc 1Qt4Ux94B11SOLB0KGS4discpbkORTCn9/m9d3fvLhXnvuHu3f+Xx/veyyfZfLSdZHzgicSfeyw4 JISwdz8FT6M8lM8Ceg385Dlhs+cC9sQCDn0B78QCogzwN+sxfHGOIXBbRGkNAM4cZymGtgNsDPgz cByxon3EEm1TLmvAlghoHOO3CZSa+IQ/vF6JV8tgKOMow78gRgL2/+EIvATOUtB3SSdMg4GXgrbn uk0uLiGdoCHKbX4E+t1FUTqn1AtIdPJebssDQ64YANSQyyaQNyUOFs0ijMsMFnOPTahPLXKYowtY 08MfCP7vR7hRnc5zmPK7CDYYbHcbC7tHuyFA94U/1LYZaJpu/sxACHMwvwZljTLY0TbNk4x+zuEt yC3MfCM6uSIvfwur0itFL4FA2Yal8BzLfnYV4EIGwEPAk7o5zIcnvzHMEjwJrrhAKK7on6IrsfRJ 7A53BhaK+CL7fj6+q/sPeOvcDTtoZTxpUYsFeIknrOXep3p3l7Ua+8sZ5FPQKyKwWi+DfROTU7ny C1/9UhpeY7K287WJCzbsNPQm2S6Yk4PSCNhWM2r3nD0K9liYb6yPgCRJhSzPrxUK0yUBVk1VX0lj s7MzGZyp0wImMK/e8rHbz2soL+O+2r1dxfGsAmBcx0lNjS/RUhlUC7gRn1wGMdQ7Vw1/AReW/RN3 xFWdAAAAAElFTkSuQmCC Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 7bit On 22.09.2013 04:06, Ken Been wrote: > I am considering using a library (serf) built on APR in my own > library. Since I'm writing a library, I can make no assumptions about > what the calling program does - it might have multiple threads started > before it calls my library, and some of those threads might be using APR. > > My library can call apr_initialize, but I can't guarantee that it > won't conflict with another call to apr_initialize in some other > thread that I don't control. Since apr_initialize doesn't seem to be > thread safe, and I don't want to put (what I consider to be) onerous > requirements on the users of my library, this effectively makes APR > unusable for me. If the application that uses your library also uses APR directly, it's already responsible for initializing it in a single-threaded context. If it doesn't, it's reasonable to require the app to call your library's init function, which you can easily protect with a spinlock (that you can implement using APR's atomic functions). > So first, is my analysis correct? Correct as far as it goes, but incomplete. > And second, if it is, is there some good reason that apr_initialize > has not been made thread safe? At first glance I think simply making > "initialized++" an atomic operation should do it, No, that wouldn't be enough. Just making the counter increment in apr_initialize (and the decrement in apr_terminate) atomic will not prevent race conditions. If two threads call apr_initialize simultaneously, one of them could return with the assumption that APR was initialized, while the second is still running the initialization code. Hence the requirement that apr_initialize must be called in a single-threaded context. That said, it would still make sense to make the counter itself atomic, if only to avoid unexpected results on architectures that do not guarantee atomic reads and writes to word-sized memory locations. > or if not then making the whole function body a critical section. I'd > be happy to work on a patch, but the fact that this hasn't been done > makes me suspect there must be a good reason for that. APR doesn't make assumptions about how an application uses it. So it's up to the caller to make sure the initialization happens in a single-threaded context. That said ... the single-threaded initialization requirement isn't as onerous as all that; it only requires the application to add two lines of code in its main function (ignoring error handling): apr_initialize(); atexit(apr_terminate()); Any non-trivial application will already have a ton of single-threaded initialization code anyway, so the above will hardly make any difference. If you don't want to expose the dependency on APR from your library, you can create your own init function that the application would call instead, and do the error handling and atexit(...) call from that. -- Brane