From owner-freebsd-hackers Sun Sep 14 19:23:18 1997 Return-Path: Received: (from root@localhost) by hub.freebsd.org (8.8.7/8.8.7) id TAA20191 for hackers-outgoing; Sun, 14 Sep 1997 19:23:18 -0700 (PDT) Received: from usr09.primenet.com (tlambert@usr09.primenet.com [206.165.6.209]) by hub.freebsd.org (8.8.7/8.8.7) with ESMTP id TAA20186 for ; Sun, 14 Sep 1997 19:23:15 -0700 (PDT) Received: (from tlambert@localhost) by usr09.primenet.com (8.8.5/8.8.5) id TAA11074; Sun, 14 Sep 1997 19:22:55 -0700 (MST) From: Terry Lambert Message-Id: <199709150222.TAA11074@usr09.primenet.com> Subject: Re: Memory leak in getservbyXXX? To: karpen@ocean.campus.luth.se (Mikael Karpberg) Date: Mon, 15 Sep 1997 02:22:55 +0000 (GMT) Cc: tlambert@primenet.com, julian@whistle.com, mike@smith.net.au, gram@cdsec.com, hackers@FreeBSD.ORG In-Reply-To: <199709150033.CAA01290@ocean.campus.luth.se> from "Mikael Karpberg" at Sep 15, 97 02:33:48 am X-Mailer: ELM [version 2.4 PL23] Content-Type: text Sender: owner-freebsd-hackers@FreeBSD.ORG X-Loop: FreeBSD.org Precedence: bulk > That seems... DUMB! Returning something that the user must free instead of > static buffers, when that's the normal behaviour is just very very bad. Say I have one of these little jewels of a function: char * static_copy( char *src) { static copy[ 128]; strcpy( copy, src); return copy; } Now say I have two threads: thread1() { char *pcopy; ... something that takes a medium time ... pcopy = static_copy( "thread 1 data"); ... something that takes a long time ... ... dosomething with pcopy ... } thread2() { char *pcopy; ... something that takes a short time ... pcopy = static_copy( "thread 2 data"); ... something that takes a medium time ... ... dosomething with pcopy ... } And I run thread 1 at the same time as thread 2. What does the buffer from the function contain when thread 1 goes to use it? What does it contain when thread 2 goes to used it? Someone gets screwed, don't they? > Three words: Thread local storage. One function name: CreateFreeeThreadedMarshallerSoICanGetAtMyOwnDamnAddressSpace() for instanced classes and objects. The *really* correct way to fix this is: somefunction( arguments, user_buffer_for_result); This ensures the data is thread local, without totally screwing up the ability to pass data by pointer among threads. And unlike traditional thread local starage, I don't have to rewrite my PTE's every time I allocate some storage, and I don't have to either go into kernel mode or run with three protection domains instead of two in order to have seperate per thread allocation spaces. And my thread-thread context switch within a single process isn't nearly as high overhead. > Let each tread have its OWN static buffer. This is actually nicer in some > ways then having the programmer pass buffers to pointers, etc, in *_r > versions of calls. It's nicer because it's less work for the user of the > library. And returning something the user must free is just out of the > question. That's ugly beyond belief. Everyone deals with their own memory. > Libraries too. Static buffers in library functions are what is ugly beyond belief. > All that is needed is [ ... ] Congradulations; you've reinvented intra-process inter-thread data marshalling... welcome to the Microsoft "Viper" framework and the ActiveX Template Library version 1.2. > Then just allocate that struct with malloc, and make a pointer > in TLS point to it. [ ... ] But why stop at Microsoft's Common Object Model (the UNIX version is called CORBA, by the way, and is generally preferred by UNIX people, as it's an open standard -- ie: documented somewhere), when you can go full steam ahead and invent Macintosh memory handles as well? AUGH! > /Mikael -- donning asbesto suit Lucky you were wearing the suit... 8-). Regards, Terry Lambert terry@lambert.org --- Any opinions in this posting are my own and not those of my present or previous employers.