/* sstring.h - Declaration of "static strings" functions */
#define COMPILING_SSTRING
+#define SSTRING_NEW
#include "sstring.h"
#include "../core/hooks.h"
static void sstringstats(int hooknum, void *arg);
static void salloc(void);
-#ifndef USE_VALGRIND
+#ifndef SSTRING_MMAP
#define sunprotect(x)
#define sunprotectb(x)
#else
+#define __USE_MISC
+
#include <sys/mman.h>
static void *mblock;
struct mblock_list {
static void *mblock_head;
#define sunprotectb(x) mprotect(x, SSTRING_ALLOC, PROT_READ|PROT_WRITE);
-#define sunprotect(x) sunprotectb(x->block);
-#define sprotect(x) mprotect(x->block, SSTRING_ALLOC, PROT_READ);
+#define sunprotect(x) sunprotectb((x)->block);
+#define sprotect(x) mprotect((x)->block, SSTRING_ALLOC, PROT_READ);
+
+#ifndef MAP_ANON
+#define MAP_ANON MAP_ANONYMOUS
+#endif
-#endif /* USE_VALGRIND */
+#endif /* SSTRING_MMAP */
void initsstring() {
int i;
registerhook(HOOK_CORE_STATSREQUEST,&sstringstats);
}
-#ifndef USE_VALGRIND
+#ifndef SSTRING_MMAP
void finisstring() {
nsfreeall(POOL_SSTRING);
}
ssmem=(char *)nsmalloc(POOL_SSTRING, SSTRING_ALLOC);
ssmemfree=SSTRING_ALLOC;
}
-#endif /* USE_VALGRIND */
+#endif /* SSTRING_MMAP */
sstring *findsstring(const char *str) {
unsigned int hash=crc32(str)%SSTRING_HASHSIZE;
sstring *ss;
for (ss=sshash[hash];ss;ss=ss->next)
- if (!strcmp(str, ss->content))
+ if (!strcmp(str, sstring_content(ss)))
return ss;
return NULL;
}
void sstring_enhash(sstring *ss) {
- unsigned int hash=crc32(ss->content)%SSTRING_HASHSIZE;
+ unsigned int hash=crc32(sstring_content(ss))%SSTRING_HASHSIZE;
ss->next=sshash[hash];
sshash[hash]=ss;
}
void sstring_dehash(sstring *ss) {
- unsigned int hash=crc32(ss->content)%SSTRING_HASHSIZE;
- sstring **ssh;
+ unsigned int hash=crc32(sstring_content(ss))%SSTRING_HASHSIZE;
+ sstring *ssh, *ssp;
- for (ssh=&(sshash[hash]); *ssh; ssh=&((*ssh)->next)) {
- if (*ssh==ss) {
- *ssh=ss->next;
+ for (ssh=sshash[hash],ssp=NULL; ssh; ssp=ssh,ssh=ssh->next) {
+ if (ssh==ss) {
+ if (!ssp) {
+ sshash[hash]=ss->next;
+ } else {
+#ifndef SSTRING_MMAP
+ ssp->next=ss->next;
+#else
+ if (ssp->block!=ss->block) {
+ sunprotect(ssp) {
+ ssp->next=ss->next;
+ } sprotect(ssp);
+ } else {
+ ssp->next=ss->next;
+ }
+#endif
+ }
return;
}
}
- Error("sstring",ERR_WARNING,"sstring_dehash(): Unable to find string (ref=%d, length=%d) in hash: %s",ss->refcount,ss->length,ss->content);
+ Error("sstring",ERR_WARNING,"sstring_dehash(): Unable to find string (ref=%lu, length=%d) in hash: %s",ss->refcount,ss->length,sstring_content(ss));
}
sstring *getsstring(const char *inputstr, int maxlen) {
/* Not enough for us - turn the remaining memory into a free string for later */
if (ssmemfree>sizeof(sstring)) {
retval=(sstring *)ssmem;
- sunprotect(retval);
+ sunprotectb(mblock);
+#ifdef SSTRING_MMAP
+ retval->block=mblock;
+#endif
retval->alloc=(ssmemfree-sizeof(sstring));
retval->refcount=0;
freesstring(retval);
*/
retval->length=(length-1);
- strcpy(retval->content,strbuf);
+ strcpy(sstring_content(retval),strbuf);
retval->refcount=1;
-
-#ifdef USE_VALGRIND
+
+#ifdef SSTRING_MMAP
if(!foreignblock)
retval->block = mblock;
#endif
sstring_enhash(retval);
+
+#ifdef SSTRING_COMPAT
+ retval->content = retval->__content;
+#endif
+
sprotect(retval);
return retval;
/* Only count calls that actually did something */
freecalls++;
+ if (inval->refcount)
+ sunprotect(inval);
+
if (inval->refcount > 1) {
- sunprotect(inval) {
- inval->refcount--;
- } sprotect(inval);
+ inval->refcount--;
+ sprotect(inval);
return;
}
/* If refcount==0 it wasn't hashed, or protected */
- if (inval->refcount) {
- sunprotect(inval);
+ if (inval->refcount)
sstring_dehash(inval);
- }
alloc=inval->alloc;
assert(alloc<=SSTRING_MAXLEN);
inval->next=freelist[alloc];
freelist[alloc]=inval;
+ sprotect(inval);
}
void sstringstats(int hooknum, void *arg) {
}
}
-int sstringcompare(sstring *ss1, sstring *ss2) {
- if (ss1->length != ss2->length)
- return -1;
-
- return strncmp(ss1->content, ss2->content, ss1->length);
-}
-
-#ifdef USE_VALGRIND
+#ifdef SSTRING_MMAP
void finisstring() {
struct mblock_list *c, *n;
for (c=mblock_head;c;c=n) {
ssmem=(char *)mblock + sizeof(struct mblock_list);
ssmemfree=SSTRING_ALLOC-sizeof(struct mblock_list);
}
-#endif /* USE_VALGRIND */
+#endif /* SSTRING_MMAP */