Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 16 Sep 1997 00:08:02 +0000 (GMT)
From:      Terry Lambert <tlambert@primenet.com>
To:        karpen@ocean.campus.luth.se (Mikael Karpberg)
Cc:        tlambert@primenet.com, hackers@FreeBSD.ORG
Subject:   Re: Memory leak in getservbyXXX?
Message-ID:  <199709160008.RAA05782@usr08.primenet.com>
In-Reply-To: <199709152300.BAA03577@ocean.campus.luth.se> from "Mikael Karpberg" at Sep 16, 97 01:00:49 am

next in thread | previous in thread | raw e-mail | index | archive | help
> > One possibility is to provide a set of library routines that take
> > a user buffer and fill it in.
> 
> Yes, that's a possiblity, and I think many wants the _r functions too.
> Which leads to double code (not double source, neccesarily though) or
> the need to call a function from a function, which gives another prob.
> How do you avoid double functioncall-time per call? Maybe you don't.
> You can probably live with that, though, specially if the functions are
> close to eachother. See my next comment also.

You don't.  This is the tax God levies on infidels who conform to
shitty standards.  The universe has no pity on morons, nor should we.
Mankind will never advance if nature does not punish stupidity and
reward intelligence.  Now ask me about seatbelt laws.  8-).


> > Provide legacy compatability with inline functions that use
> > static buffers as the argument to the real functions.  This
> > immediately buys the functions into being threadsafe as well, since
> > each reference instance will have its own buffer.
> 
> Is it possible to use a static buffer in an inline function? That means
> that it's either in one place and all references use it, or that it's
> a static buffer in each reference, I guess. Neither is threadsafe.

The first is not what happens; you are thinking like a C++ programmer.
The second is threadsafe, actually, it's just wasteful.  If you don't
want to be wasteful, use the good interface.  Otherwise, lump it;
consider it a fine for using the bad interface and engaging in poor
programming techniques by not centralizing references to code
outside your control.  It's not reasonable for you to be calling
getpwent() in 400 places in your code anyway; you code would be
non-portable as heck.


> Wrapper functions (inline or not) have some problems:
> 1) can't return a stack-allocated space (except possibly with some gcc quirk)

You can't do that anyway.  Maybe you are thinking of calling a function
with an auto buffer, the inverse case?  That works, too.

> 2) can't use static buffers because it's not thread safe.

You can, and it is.  The static buffers are inlined at ever reference,
and locally scoped.


> 3) can't use malloc to get a buffer because then they are allocating but not
>    taking care of freeing themselfs.

THat's the current POSIX 1003.4 accepted practice that you are complaining
about.  I dislike non-reflexive interfaces as well.  You should be
arguing on my side for the namei(0 patches, where the underlying FS is
expected to free the caller's path name buffer.  Bletch.


> Basically the only solution I can see to do it (no matter if you don't have
> *_r calls, if you call them from wrappers, or if you double the code), is to
> use TSD. And a TSD pointer to a malloc()ated structure which holds all the
> buffers seems like the fastest and safest way to do it.

The static stuff works, too, for thread safe legacy interfaces.  Really.
It just puishes the users of the legacy interfaces with data space bloat,
charged per use of the interface.


> The TLS doesn't need to be mapped into the same address space, but can be.

If it's not, then I can't use a constructed object from one thread
in another thread without proxying it between the different TLS address
spaces.  Which is why I hate that idea.  Have you ever programmed
Apartment or Freethreaded code on NT or 95?  No thank you!


> It doesn't matter since the info in the TLS will only be a single pointer,
> which should never be referenced outside the library, and never passed
> between threads inside the library. The struct itself is allocated outside
> TLS, but kept track on by a TLS pointer.

How do I pass a struct pwent * from a getpwent() in thread 1 to thread 2?
I'd have to maintain a reference count on the externally allocated storage,
and pss it with a function that incremented the reference count and
produced a TLS handle in the new threads space to point to the shared
object.  If I didn't, and thread 1 got the entry, passed it to thread 2,
then exited, your TLS pointer will have gone out of scope in thread_exit(),
and the storage would be available for reallocation (if it wasn't, I would
be unable to stop and start 100,000 threads without a memeory leak each
time).

All of this neglects that Fact the FreeBSD does not have thread local
storage because we thing that rewriting a page table descriptor on
a thread context switch is the fastes way to make it so that thread
context switches aren't a win relative to process context siwtches --
after which, tell us why we are using threads instead of vfork?  Ah...
I remember... it's so that we get fewer quanta, that's it...  8-(.
Might as well be SVR4 or Solaris, at that point, both of which blow off
hughe amounts of quanta in kernel thread context switch overhead, all
in the name of not having to do a marginally more complex implementation.


> > It's possible to provide dynmaic scoping in C as well.  It's just
> > high overhead.  Just as it is in C++.  Which is one of the reasons
> > the kernel isn't written in C++.  But it *is* possible.
> 
> Er... What is dynamic scoping?

When you exit a scope, you destroy the objects created in the scope.

> And passing objects back relies on ctors/dtors which C doesn't have.

__asm(); it's only the threads scheduler in general, and thread_exit()
in particular, that need to have it.

> but it requires macros and/or extra work by the programmer, which can't
> be expected of him (like calling destructors by hand, which can be
> forgotten).

It's the threads library -- in other words, infrastructure that everyone
but the threads library programmer can assume exists.

> [ don't have time for more right now, and FreeBSD changing
> standards? Likely. ]

Not required.  People can use the legacy interface.  More power (and
a larger RSS) to them...


					Terry Lambert
					terry@lambert.org
---
Any opinions in this posting are my own and not those of my present
or previous employers.



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199709160008.RAA05782>