implemented talloc() as described on samba-technical. This fixes the
authorAndrew Tridgell <tridge@samba.org>
Wed, 5 Jan 2000 06:36:36 +0000 (06:36 +0000)
committerAndrew Tridgell <tridge@samba.org>
Wed, 5 Jan 2000 06:36:36 +0000 (06:36 +0000)
lp_string() bug properly.

we still need to add lp_talloc_free() calls in all the main event
loops, I've only put it in smbd and nmbd thus far.

source/Makefile.in
source/include/includes.h
source/include/proto.h
source/include/talloc.h [new file with mode: 0644]
source/lib/talloc.c [new file with mode: 0644]
source/nmbd/nmbd.c
source/param/loadparm.c
source/script/mkproto.awk
source/smbd/process.c

index acf7c02c21ae32151ca9421c4ed4590df6e95dbb..6201e63c88695d997141e9948f11a4b554acc216 100644 (file)
@@ -99,7 +99,7 @@ LIB_OBJ = lib/charcnv.o lib/charset.o lib/debug.o lib/fault.o \
          lib/util_array.o lib/util_str.o lib/util_sid.o \
          lib/util_unistr.o lib/util_file.o \
          lib/util.o lib/util_sock.o lib/util_sec.o smbd/ssl.o lib/fnmatch.o \
-         tdb/tdb.o
+         tdb/tdb.o lib/talloc.o
 
 UBIQX_OBJ = ubiqx/ubi_BinTree.o ubiqx/ubi_Cache.o ubiqx/ubi_SplayTree.o \
             ubiqx/ubi_dLinkList.o ubiqx/ubi_sLinkList.o ubiqx/debugparse.o
index 3e9010bf548b19c5aa6ec2cb4be338f5bbd3bd07..7986c12c91a9778ff2b6d984c5ae1dbd4cd0d596 100644 (file)
@@ -611,6 +611,7 @@ extern int errno;
 #include "ubi_dLinkList.h"
 #include "dlinklist.h"
 #include "../tdb/tdb.h"
+#include "talloc.h"
 #include "interfaces.h"
 
 #ifdef HAVE_FNMATCH
index bb1d5477dfca6679eb1318b633b9726e6f717a2a..0222e890d21a7dd721c7b3f65906521188f075d4 100644 (file)
@@ -223,6 +223,12 @@ smb_ucs2_t *wsys_getwd(smb_ucs2_t *s);
 int wsys_chown(const smb_ucs2_t *wfname, uid_t uid, gid_t gid);
 int wsys_chroot(const smb_ucs2_t *wfname);
 
+/*The following definitions come from  lib/talloc.c  */
+
+TALLOC_CTX *talloc_init(void);
+void *talloc(TALLOC_CTX *t, size_t size);
+void talloc_destroy(TALLOC_CTX *t);
+
 /*The following definitions come from  lib/time.c  */
 
 void GetTimeOfDay(struct timeval *tval);
@@ -1111,6 +1117,7 @@ void expire_workgroups_and_servers(time_t t);
 
 /*The following definitions come from  param/loadparm.c  */
 
+void lp_talloc_free(void);
 char *lp_logfile(void);
 char *lp_smbrun(void);
 char *lp_configfile(void);
diff --git a/source/include/talloc.h b/source/include/talloc.h
new file mode 100644 (file)
index 0000000..df68166
--- /dev/null
@@ -0,0 +1,32 @@
+/* 
+   Unix SMB/Netbios implementation.
+   Version 3.0
+   Samba temporary memory allocation functions
+   Copyright (C) Andrew Tridgell 2000
+   
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2 of the License, or
+   (at your option) any later version.
+   
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+   
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+struct talloc_chunk {
+       struct talloc_chunk *next;
+       void *ptr;
+       size_t alloc_size;
+       size_t total_size;
+};
+
+typedef struct {
+       struct talloc_chunk *list;
+} TALLOC_CTX;
+
diff --git a/source/lib/talloc.c b/source/lib/talloc.c
new file mode 100644 (file)
index 0000000..518237c
--- /dev/null
@@ -0,0 +1,96 @@
+/* 
+   Unix SMB/Netbios implementation.
+   Version 3.0
+   Samba temporary memory allocation functions
+   Copyright (C) Andrew Tridgell 2000
+   
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2 of the License, or
+   (at your option) any later version.
+   
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+   
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+/* this is a very simple temporary memory allocator. To use it do the following:
+
+   1) when you first want to allocate a pool of meomry use
+   talloc_init() and save the resulting context pointer somewhere
+
+   2) to allocate memory use talloc()
+
+   3) when _all_ of the memory allocated using this context is no longer needed
+   use talloc_destroy()
+
+   talloc does not zero the memory. It guarantees memory of a
+   TALLOC_ALIGN alignment
+*/
+
+#include "includes.h"
+
+#define TALLOC_ALIGN 32
+#define TALLOC_CHUNK_SIZE (0x2000)
+
+/* initialissa talloc context. */
+TALLOC_CTX *talloc_init(void)
+{
+       TALLOC_CTX *t;
+
+       t = (TALLOC_CTX *)malloc(sizeof(*t));
+       if (!t) return NULL;
+
+       t->list = NULL;
+
+       return t;
+}
+
+/* allocate a bit of memory from the specified pool */
+void *talloc(TALLOC_CTX *t, size_t size)
+{
+       void *p;
+
+       size = (size + TALLOC_ALIGN) & (~TALLOC_ALIGN-1);
+
+       if (!t->list || (t->list->total_size - t->list->alloc_size) < size) {
+               struct talloc_chunk *c;
+               size_t asize = (size + TALLOC_CHUNK_SIZE) & ~(TALLOC_CHUNK_SIZE-1);
+
+               c = (struct talloc_chunk *)malloc(sizeof(*c));
+               if (!c) return NULL;
+               c->next = t->list;
+               c->ptr = (void *)malloc(asize);
+               if (!c->ptr) {
+                       free(c);
+                       return NULL;
+               }
+               c->alloc_size = 0;
+               c->total_size = asize;
+               t->list = c;
+       }
+
+       p = t->list->ptr + t->list->alloc_size;
+       t->list->alloc_size += size;
+       return p;
+}
+
+/* destroy a whole pool */
+void talloc_destroy(TALLOC_CTX *t)
+{
+       struct talloc_chunk *c;
+       
+       while (t->list) {
+               c = t->list->next;
+               free(t->list->ptr);
+               free(t->list);
+               t->list = c;
+       }
+
+       free(t);
+}
index 751aede39420e060074c4f21231e9f16c2a5245d..5bb3d7fc00dbd6c18f3e51b3e842525b852a7d04 100644 (file)
@@ -475,6 +475,9 @@ static void process(void)
 
     /* check for new network interfaces */
     reload_interfaces(t);
+
+    /* free up temp memory */
+    lp_talloc_free();
   }
 } /* process */
 
index 6d825541302e64eb847752964ace0c60e58cb30f..b76af54609835b9443ffa0d12bebb0ea9cc985e2 100644 (file)
@@ -1092,55 +1092,43 @@ static void init_locals(void)
 
 #define NUMBER_OF_STATIC_STRING_BUFS 20
 
+static TALLOC_CTX *lp_talloc;
+
 /******************************************************************* a
-convenience routine to grab string parameters into a rotating buffer,
+free up temporary memory - called from the main loop
+********************************************************************/
+void lp_talloc_free(void)
+{
+       if (!lp_talloc) return;
+       talloc_destroy(lp_talloc);
+       lp_talloc = NULL;
+}
+
+/*******************************************************************
+convenience routine to grab string parameters into temporary memory
 and run standard_sub_basic on them. The buffers can be written to by
 callers without affecting the source string.
 ********************************************************************/
 static char *lp_string(const char *s)
 {
-  static char *bufs[NUMBER_OF_STATIC_STRING_BUFS];
-  static size_t buflen[NUMBER_OF_STATIC_STRING_BUFS];
-  static int next = -1;  
-  char *ret;
-  int i;
-  size_t len = s?strlen(s):0;
-
-  if (next == -1) {
-    /* initialisation */
-    for (i=0;i<NUMBER_OF_STATIC_STRING_BUFS;i++) {
-      bufs[i] = NULL;
-      buflen[i] = 0;
-    }
-    next = 0;
-  }
+       size_t len = s?strlen(s):0;
+       char *ret;
 
-  len = MAX(len+100,sizeof(pstring)); /* the +100 is for some
-                                        substitution room */
-
-  if (buflen[next] != len) {
-    buflen[next] = len;
-    if (bufs[next])
-      free(bufs[next]);
-    bufs[next] = (char *)malloc(len);
-    if (!bufs[next]) {
-      DEBUG(0,("out of memory in lp_string()"));
-      exit(1);
-    }
-  } 
+       if (!lp_talloc) lp_talloc = talloc_init();
+  
+       ret = (char *)talloc(lp_talloc, len + 100); /* leave room for substitution */
 
-  ret = &bufs[next][0];
-  next = (next+1)%NUMBER_OF_STATIC_STRING_BUFS;
+       if (!ret) return NULL;
 
-  if (!s) 
-    *ret = 0;
-  else
-    StrnCpy(ret,s,len-1);
+       if (!s) 
+               *ret = 0;
+       else
+               StrnCpy(ret,s,len);
 
-  trim_string(ret, "\"", "\"");
+       trim_string(ret, "\"", "\"");
 
-  standard_sub_basic(ret);
-  return(ret);
+       standard_sub_basic(ret);
+       return(ret);
 }
 
 
@@ -2601,7 +2589,7 @@ BOOL lp_load(char *pszFname,BOOL global_only, BOOL save_defaults, BOOL add_ipc)
 {
   pstring n2;
   BOOL bRetval;
+
   add_to_file_list(pszFname);
 
   bRetval = False;
index c24dfac98cc6ce122a3217852c1f2da1d3de7b23..8ef414266abe9d826c36ed7b44a29102955577f4 100644 (file)
@@ -98,7 +98,7 @@ END {
     gotstart = 1;
   }
 
-  if( $0 ~ /^TDB_CONTEXT|^TDB_DATA|^smb_ucs2_t/ ) {
+  if( $0 ~ /^TDB_CONTEXT|^TDB_DATA|^smb_ucs2_t|^TALLOC_CTX/ ) {
     gotstart = 1;
   }
 
index 36eb8823406901364235db5f6d36c793fa4ccadb..04432adb9698ffeb7f7518dd3c16a301ce969a5c 100644 (file)
@@ -1018,6 +1018,9 @@ void smbd_process(void)
 
     errno = 0;      
 
+    /* free up temporary memory */
+    lp_talloc_free();
+
     while(!receive_message_or_smb(InBuffer,BUFFER_SIZE,select_timeout,&got_smb))
     {
       if(!timeout_processing( deadtime, &select_timeout, &last_timeout_processing_time))