[tech] Mac stuff

David Luyer david at luyer.net
Wed Apr 17 23:39:45 WST 2002


> The trouble is dealing with bits of state when your connection
> suddenly dies. Squid has tried to do it using a callback/refcounted
> struct - you lock/unlock structs, and you call free() when 
> you're finished - and everything that uses it does a
> 
> if (cbdataValid(pointer))
[...]
> which prevents now-dead structs from actually being read.
> 
> I think its the wrong solution, but i haven't figure out
> a better one just yet. Guess I should try implementing a simple
> http proxy using my library. :)

I don't like any of the callback data refcounting stuff.  This is
where java and perl just win, but they're not an option for things
where I'm looking at kernel-side acceleration... rather than JVM
or perl deceleration.  Although my RADIUS server is written in perl
and beats all C-based ones I've seen simply through algorithms I
wouldn't have considered writing in C because it would just have
been too hard (of course, I could in theory translate it to C now
and get a speedup, but at the moment it's quite nice in perl).

My current approach is to attempt to avoid data that has to be
free'd - which isn't going to always be possible, but in many
cases it is possible and again a speedup to avoid allocating and
deallocating memory.

eg. my standard event runner contains (standard copyright applies,
all code I write, whether for my employer or not, is automatically
copyright by my employer, unfortunately -- I get away with
contributions to projects already under GPL, fortunately, though):

/* The below code is COPYRIGHT (c) 2002 Pacific Internet,
 * all rights reserved.
 *
 * This code may not be compiled in any situation.
 *
 * This code is provided to members of this list only as an illustration
 * of coding style.
 *
 * In fact, this is not code.  It is free form text which is not meant
 * to resemble or represent any programming language.  And it is
 * deliberately incomplete, so even if it were code, it would not work.
 */

#define eprintf(X, ...) \
        fprintf(stderr, __FUNCTION__ ": " X "\n" , ## __VA_ARGS__)

/* Queue length (entries), size (allocated), position (next event) */
static int eventQueueLen = 0, eventQueueSz = 0, eventQueuePos = -1;
static event *eventQueue = NULL;

extern void add_event_absolute(struct timeval *t, event_function f, void
*data) {
  int newpos;

  if (eventQueueLen == eventQueueSz) {
    eventQueue = realloc(eventQueue, (++eventQueueSz) * sizeof(event));
    if (!eventQueue) {
      eprintf("realloc failed for eventQueue!");
      exit(1);
    }
  }
  newpos = ((eventQueuePos++) + eventQueueLen) % eventQueueSz;
  eventQueue[newpos].t.tv_sec = t->tv_sec;
  eventQueue[newpos].t.tv_usec = t->tv_usec;
  eventQueue[newpos].run = f;
  eventQueue[newpos].data = data;
}

David.



More information about the tech mailing list