From owner-freebsd-hackers Mon Oct 29 4:43: 0 2001 Delivered-To: freebsd-hackers@freebsd.org Received: from pcnet1.pcnet.com (pcnet1.pcnet.com [204.213.232.3]) by hub.freebsd.org (Postfix) with ESMTP id CCD9637B405 for ; Mon, 29 Oct 2001 04:42:54 -0800 (PST) Received: (from eischen@localhost) by pcnet1.pcnet.com (8.8.7/PCNet) id HAA29502; Mon, 29 Oct 2001 07:41:37 -0500 (EST) Date: Mon, 29 Oct 2001 07:41:37 -0500 (EST) From: Daniel Eischen To: Lamont Granquist Cc: freebsd-hackers@FreeBSD.ORG Subject: Re: MT-Safe wrapper around memcpy()? In-Reply-To: <20011029040255.D27876-100000@coredump.scriptkiddie.org> Message-ID: MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII Sender: owner-freebsd-hackers@FreeBSD.ORG Precedence: bulk List-ID: List-Archive: (Web Archive) List-Help: (List Instructions) List-Subscribe: List-Unsubscribe: X-Loop: FreeBSD.ORG On Mon, 29 Oct 2001, Lamont Granquist wrote: > On Mon, 29 Oct 2001, Alfred Perlstein wrote: > > * Alfred Perlstein [011029 00:53] wrote: > > > * Lamont Granquist [011029 00:43] wrote: > > > > > > > > I'm trying to figure out the best way to write a wrapper around memcpy() > > > > which can call fprintf() without winding up getting into a recursive > > > > loop. The problem is that fprintf() will call memcpy() and around and > > > > around we go. > > > > > > > > I can use a global variable to prevent this, but that usage isn't thread > > > > safe. I can make it thread safe by using pthread keys, but then i have to > > > > link in libc_r, and for non-pthreaded programs i don't want to do that. > > > > > > > > Anyone have any suggestions? Right now I'm almost thinking that I just > > > > need to directly patch libc and libc_r. It might be an ugly patch though, > > > > and I'd rather not have this patch mandate recompiling all of libc. > > > > > > Where do you see mem* calling printf? > > > > Uh, nevermind. :) > > > > Ok, what you want to do is use a nested flag in memcpy so you > > don't recurse, there's some code in libc that's conditionally > > compiled when compiling libc_r, _THREAD_SAFE or something is > > defined, once you find that then just simply use the global > > for non threaded programs and keys for threaded ones. > > you mean like localtime.c: > > #ifdef _THREAD_SAFE > pthread_mutex_lock(&lcl_mutex); > #endif > > and such? The _THREAD_SAFE macro has gone away anyways (in -current), and we (FreeBSD) shouldn't be conditionally compiling code in libc dependent on whether libc_r is being built or not. And I wouldn't recommend it for user libraries either. Take a look at how libgcc works (src/contrib/gcc.295/gthr-posix.h). In your application library, make wrapper functions for whatever thread routines you need to use in a threaded application. Then make weak _references_ to the actual (non-wrapped) pthread routines. So you'd have something like: /* File mylib_threads.c */ #pragma weak pthread_mutex_lock #pragma weak pthread_mutex_unlock #pragma weak pthread_key_create #pragma weak pthread_key_delete #pragma weak pthread_once [add any others you might need] #pragma weak pthread_create static void app_is_threaded = &pthread_create; int mylib_is_threaded(void) { return (app_is_threaded != NULL); } int mylib_pthread_mutex_lock(pthread_mutex_t *mutex) { if (mylib_is_threaded()) return (pthread_mutex_lock(mutex); else return (0); } ... By making the references to pthread_* weak, the linker will not barf if libc_r isn't linked in, and all references will be NULL. If the application is threaded (libc_r is linked in), then those references will be resolved. Make sure the weak pragmas are localized to the file that actually implements the wrapper functions. You don't want them visible to other files that directly use pthreads. -- Dan Eischen To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-hackers" in the body of the message