void n64_free(void *buf) { if (NULL == buf) { null_frees += 1; return; } kv_t *kv = mapfind(kv_set, ((uint32_t)&buf)&0x0FFFFFFF); // it got malloc'd but we missed it if (0 == kv) { unmapped_frees += 1; free(buf); } // we saw the malloc too else { int size_to_free = kv->size; mapremove(kv_set, ((uint32_t)&buf)&0x0FFFFFFF); free(buf); allocated_bytes -= size_to_free; } }
/*}}}*/ }; int xchar_length (xchar_t ch) /*{{{*/ { return utf8_length_tab[ch]; }/*}}}*/ int xchar_strict_length (xchar_t ch) /*{{{*/ { return utf8_strict_length_tab[ch]; }/*}}}*/ int xchar_valid_position (const xchar_t *s, int length) /*{{{*/ { # define VALID(ccc) (((ccc) & 0xc0) == 0x80) int len, n; if (((len = xchar_strict_length (*s)) > 0) && (length >= len)) for (n = len; n > 1; ) { --n; if (! VALID (*(s + n))) { len = -1; break; } } else len = -1; return len; # undef VALID }/*}}}*/ bool_t xchar_valid (const xchar_t *s, int length) /*{{{*/ { int n; while (length > 0) if ((n = xchar_valid_position (s, length)) > 0) { s += n; length -= n; } else break; return length == 0 ? true : false; }/*}}}*/ const char * xchar_to_char (const xchar_t *s) /*{{{*/ { return (const char *) s; }/*}}}*/ const xchar_t * char_2_xchar (const char *s) /*{{{*/ { return (const xchar_t *) s; }/*}}}*/ const char * byte_to_char (const byte_t *b) /*{{{*/ { return (const char *) b; }/*}}}*/ int xstrlen (const xchar_t *s) /*{{{*/ { int len, clen; for (len = 0; *s; ++len) { clen = xchar_length (*s); while ((clen-- > 0) && *s) ++s; } return len; }/*}}}*/ int xstrcmp (const xchar_t *s1, const char *s2) /*{{{*/ { return strcmp (xchar_to_char (s1), s2); }/*}}}*/ int xstrncmp (const xchar_t *s1, const char *s2, size_t n) /*{{{*/ { return strncmp (xchar_to_char (s1), s2, n); }/*}}}*/ bool_t xmlbuf_equal (xmlbuf_t *b1, xmlbuf_t *b2) /*{{{*/ { if ((! b1) && (! b2)) return true; if (b1 && b2 && (b1 -> length == b2 -> length) && ((! b1 -> length) || (! memcmp (b1 -> buffer, b2 -> buffer, b1 -> length)))) return true; return false; }/*}}}*/ char * xmlbuf_to_string (xmlbuf_t *b) /*{{{*/ { return buffer_copystring ((buffer_t *) b); }/*}}}*/ long xmlbuf_to_long (xmlbuf_t *b) /*{{{*/ { const char *s = b ? buffer_string (b) : NULL; return s ? strtol (s, NULL, 0) : -1; }/*}}}*/ static inline unsigned long mkcp (const xchar_t *s, int *len) /*{{{*/ { unsigned long cp; int n; *len = xchar_length (*s); for (n = 0, cp = 0; n < *len; ++n) { cp <<= 8; cp |= s[n]; } return cp; }/*}}}*/ static inline const utfmap_t * mapfind (const xchar_t *s, int *len, const utfmap_t *map, int msize) /*{{{*/ { unsigned long cp; int low, high, pos; int dummy; cp = mkcp (s, len ? len : & dummy); for (low = 0, high = msize; low < high; ) { pos = (low + high) >> 1; if (map[pos].cp == cp) return & map[pos]; else if (map[pos].cp < cp) low = pos + 1; else high = pos; } return NULL; }/*}}}*/ static inline bool_t isword (const xchar_t *s) /*{{{*/ { unsigned long cp; int len; cp = mkcp (s, & len); if (len == 1) return isalnum (s[0]) ? true : false; else { int low, high, pos; for (low = 0, high = is_word_length; low < high;) { pos = (low + high) >> 1; if (is_word[pos] == cp) return true; if (is_word[pos] < cp) low = pos + 1; else high = pos; } } return false; }/*}}}*/ static inline const xchar_t * mapper (const utfmap_t *map, int msize, const xchar_t *s, int *slen, int *olen) /*{{{*/ { const utfmap_t *m = mapfind (s, slen, map, msize); if (m) { if (olen) *olen = m -> dlen; return m -> dst; } return NULL; }/*}}}*/
session_t *session_lookup(uint64_t sessionid) { if (sessionid == 0) { return NULL; } union Key k = {.u64 = sessionid}; qlock(&session_map_mutex); session_t **sessionpp = (session_t**)mapfind(&session_map, k); if (sessionpp == NULL) { printf("session_lookup: invalid session\n"); return NULL; } session_lock(*sessionpp); (*sessionpp)->refcount++; if ((*sessionpp)->refcount > 4) { printf("session_lookup: %d references to the same session, code error is likely\n", (*sessionpp)->refcount); } session_unlock(*sessionpp); qunlock(&session_map_mutex); return *sessionpp; }