diff --git a/.clang-format b/.clang-format new file mode 100644 index 00000000..e147cb35 --- /dev/null +++ b/.clang-format @@ -0,0 +1,20 @@ +BasedOnStyle: LLVM +AlignConsecutiveAssignments: true +AllowShortFunctionsOnASingleLine: false +AllowShortIfStatementsOnASingleLine: false +AllowShortLoopsOnASingleLine: false +AlwaysBreakAfterDefinitionReturnType: true +AlwaysBreakBeforeMultilineStrings: true +BinPackParameters: false +BreakBeforeBraces: Linux +BreakConstructorInitializersBeforeComma: true +ColumnLimit: 120 +ContinuationIndentWidth: 2 +Cpp11BracedListStyle: false +DerivePointerAlignment: false +IndentWidth: 4 +PointerAlignment: Left +SortIncludes: false +SpaceAfterCStyleCast: true +TabWidth: 4 +UseTab: Never diff --git a/apc.c b/apc.c index a64eb013..394caa83 100644 --- a/apc.c +++ b/apc.c @@ -37,15 +37,16 @@ #include "php.h" #if HAVE_PCRE || HAVE_BUNDLED_PCRE -# include "ext/pcre/php_pcre.h" -# include "zend_smart_str.h" +#include "ext/pcre/php_pcre.h" +#include "zend_smart_str.h" #endif -#define NELEMS(a) (sizeof(a)/sizeof((a)[0])) +#define NELEMS(a) (sizeof(a) / sizeof((a)[0])) /* {{{ memory allocation wrappers */ -PHP_APCU_API void* apc_emalloc(size_t n) +PHP_APCU_API void* +apc_emalloc(size_t n) { void* p = malloc(n); if (p == NULL) { @@ -55,9 +56,10 @@ PHP_APCU_API void* apc_emalloc(size_t n) return p; } -PHP_APCU_API void* apc_erealloc(void* p, size_t n) +PHP_APCU_API void* +apc_erealloc(void* p, size_t n) { - void *new; + void* new; new = realloc(p, n); if (new == NULL) { apc_error("apc_erealloc: realloc failed to allocate %u bytes:", n); @@ -66,7 +68,8 @@ PHP_APCU_API void* apc_erealloc(void* p, size_t n) return new; } -PHP_APCU_API void apc_efree(void* p) +PHP_APCU_API void +apc_efree(void* p) { if (p == NULL) { apc_error("apc_efree: attempt to free null pointer"); @@ -75,17 +78,20 @@ PHP_APCU_API void apc_efree(void* p) free(p); } -PHP_APCU_API void* apc_php_malloc(size_t n) +PHP_APCU_API void* +apc_php_malloc(size_t n) { return emalloc(n); } -PHP_APCU_API void apc_php_free(void* p) +PHP_APCU_API void +apc_php_free(void* p) { efree(p); } -PHP_APCU_API char* APC_ALLOC apc_estrdup(const char* s) +PHP_APCU_API char* APC_ALLOC +apc_estrdup(const char* s) { int len; char* dup; @@ -94,9 +100,9 @@ PHP_APCU_API char* APC_ALLOC apc_estrdup(const char* s) return NULL; } len = strlen(s); - dup = (char*) malloc(len+1); + dup = (char*) malloc(len + 1); if (dup == NULL) { - apc_error("apc_estrdup: malloc failed to allocate %u bytes:", len+1); + apc_error("apc_estrdup: malloc failed to allocate %u bytes:", len + 1); return NULL; } memcpy(dup, s, len); @@ -104,12 +110,14 @@ PHP_APCU_API char* APC_ALLOC apc_estrdup(const char* s) return dup; } -PHP_APCU_API void* APC_ALLOC apc_xstrdup(const char* s, apc_malloc_t f) +PHP_APCU_API void* APC_ALLOC +apc_xstrdup(const char* s, apc_malloc_t f) { - return s != NULL ? apc_xmemcpy(s, strlen(s)+1, f) : NULL; + return s != NULL ? apc_xmemcpy(s, strlen(s) + 1, f) : NULL; } -PHP_APCU_API void* APC_ALLOC apc_xmemcpy(const void* p, size_t n, apc_malloc_t f) +PHP_APCU_API void* APC_ALLOC +apc_xmemcpy(const void* p, size_t n, apc_malloc_t f) { void* q; @@ -123,15 +131,15 @@ PHP_APCU_API void* APC_ALLOC apc_xmemcpy(const void* p, size_t n, apc_malloc_t f /* }}} */ /* {{{ console display functions */ -#define APC_PRINT_FUNCTION(name, verbosity) \ - void apc_##name(const char *format, ...) \ - { \ - va_list args; \ - \ - va_start(args, format); \ - php_verror(NULL, "", verbosity, format, args); \ - va_end(args); \ - } +#define APC_PRINT_FUNCTION(name, verbosity) \ + void apc_##name(const char* format, ...) \ + { \ + va_list args; \ + \ + va_start(args, format); \ + php_verror(NULL, "", verbosity, format, args); \ + va_end(args); \ + } APC_PRINT_FUNCTION(error, E_ERROR) APC_PRINT_FUNCTION(warning, E_WARNING) @@ -140,13 +148,17 @@ APC_PRINT_FUNCTION(notice, E_NOTICE) #ifdef APC_DEBUG APC_PRINT_FUNCTION(debug, E_NOTICE) #else -void apc_debug(const char *format, ...) {} +void +apc_debug(const char* format, ...) +{ +} #endif /* }}} */ /* {{{ string and text manipulation */ -char* apc_append(const char* s, const char* t) +char* +apc_append(const char* s, const char* t) { int slen; int tlen; @@ -162,7 +174,8 @@ char* apc_append(const char* s, const char* t) return p; } -char* apc_substr(const char* s, int start, int length) +char* +apc_substr(const char* s, int start, int length) { char* substr; int src_len = strlen(s); @@ -170,8 +183,7 @@ char* apc_substr(const char* s, int start, int length) /* bring start into range */ if (start < 0) { start = 0; - } - else if (start >= src_len) { + } else if (start >= src_len) { start = src_len - 1; } @@ -181,19 +193,20 @@ char* apc_substr(const char* s, int start, int length) } /* create the substring */ - substr = apc_xmemcpy(s + start, length + 1, apc_emalloc); + substr = apc_xmemcpy(s + start, length + 1, apc_emalloc); substr[length] = '\0'; return substr; } -char** apc_tokenize(const char* s, char delim) +char** +apc_tokenize(const char* s, char delim) { - char** tokens; /* array of tokens, NULL terminated */ - int size; /* size of tokens array */ - int n; /* index of next token in tokens array */ - int cur; /* current position in input string */ - int end; /* final legal position in input string */ - int next; /* position of next delimiter in input */ + char** tokens; /* array of tokens, NULL terminated */ + int size; /* size of tokens array */ + int n; /* index of next token in tokens array */ + int cur; /* current position in input string */ + int end; /* final legal position in input string */ + int next; /* position of next delimiter in input */ if (!s) { return NULL; @@ -204,25 +217,25 @@ char** apc_tokenize(const char* s, char delim) cur = 0; end = strlen(s) - 1; - tokens = (char**) apc_emalloc(size * sizeof(char*)); + tokens = (char**) apc_emalloc(size * sizeof(char*)); tokens[n] = NULL; while (cur <= end) { /* search for the next delimiter */ char* p = strchr(s + cur, delim); - next = p ? p-s : end+1; + next = p ? p - s : end + 1; /* resize token array if necessary */ - if (n == size-1) { + if (n == size - 1) { size *= 2; tokens = (char**) apc_erealloc(tokens, size * sizeof(char*)); } /* save the current token */ - tokens[n] = apc_substr(s, cur, next-cur); + tokens[n] = apc_substr(s, cur, next - cur); tokens[++n] = NULL; - cur = next + 1; + cur = next + 1; } return tokens; @@ -234,73 +247,74 @@ char** apc_tokenize(const char* s, char delim) /* this table was generated by crc32gen() */ static unsigned int crc32tab[] = { - /* 0 */ 0x00000000, 0x3b83984b, 0x77073096, 0x4c84a8dd, - /* 4 */ 0xee0e612c, 0xd58df967, 0x990951ba, 0xa28ac9f1, - /* 8 */ 0x076dc419, 0x3cee5c52, 0x706af48f, 0x4be96cc4, - /* 12 */ 0xe963a535, 0xd2e03d7e, 0x9e6495a3, 0xa5e70de8, - /* 16 */ 0x0edb8832, 0x35581079, 0x79dcb8a4, 0x425f20ef, - /* 20 */ 0xe0d5e91e, 0xdb567155, 0x97d2d988, 0xac5141c3, - /* 24 */ 0x09b64c2b, 0x3235d460, 0x7eb17cbd, 0x4532e4f6, - /* 28 */ 0xe7b82d07, 0xdc3bb54c, 0x90bf1d91, 0xab3c85da, - /* 32 */ 0x1db71064, 0x2634882f, 0x6ab020f2, 0x5133b8b9, - /* 36 */ 0xf3b97148, 0xc83ae903, 0x84be41de, 0xbf3dd995, - /* 40 */ 0x1adad47d, 0x21594c36, 0x6ddde4eb, 0x565e7ca0, - /* 44 */ 0xf4d4b551, 0xcf572d1a, 0x83d385c7, 0xb8501d8c, - /* 48 */ 0x136c9856, 0x28ef001d, 0x646ba8c0, 0x5fe8308b, - /* 52 */ 0xfd62f97a, 0xc6e16131, 0x8a65c9ec, 0xb1e651a7, - /* 56 */ 0x14015c4f, 0x2f82c404, 0x63066cd9, 0x5885f492, - /* 60 */ 0xfa0f3d63, 0xc18ca528, 0x8d080df5, 0xb68b95be, - /* 64 */ 0x3b6e20c8, 0x00edb883, 0x4c69105e, 0x77ea8815, - /* 68 */ 0xd56041e4, 0xeee3d9af, 0xa2677172, 0x99e4e939, - /* 72 */ 0x3c03e4d1, 0x07807c9a, 0x4b04d447, 0x70874c0c, - /* 76 */ 0xd20d85fd, 0xe98e1db6, 0xa50ab56b, 0x9e892d20, - /* 80 */ 0x35b5a8fa, 0x0e3630b1, 0x42b2986c, 0x79310027, - /* 84 */ 0xdbbbc9d6, 0xe038519d, 0xacbcf940, 0x973f610b, - /* 88 */ 0x32d86ce3, 0x095bf4a8, 0x45df5c75, 0x7e5cc43e, - /* 92 */ 0xdcd60dcf, 0xe7559584, 0xabd13d59, 0x9052a512, - /* 96 */ 0x26d930ac, 0x1d5aa8e7, 0x51de003a, 0x6a5d9871, - /* 100 */ 0xc8d75180, 0xf354c9cb, 0xbfd06116, 0x8453f95d, - /* 104 */ 0x21b4f4b5, 0x1a376cfe, 0x56b3c423, 0x6d305c68, - /* 108 */ 0xcfba9599, 0xf4390dd2, 0xb8bda50f, 0x833e3d44, - /* 112 */ 0x2802b89e, 0x138120d5, 0x5f058808, 0x64861043, - /* 116 */ 0xc60cd9b2, 0xfd8f41f9, 0xb10be924, 0x8a88716f, - /* 120 */ 0x2f6f7c87, 0x14ece4cc, 0x58684c11, 0x63ebd45a, - /* 124 */ 0xc1611dab, 0xfae285e0, 0xb6662d3d, 0x8de5b576, - /* 128 */ 0x76dc4190, 0x4d5fd9db, 0x01db7106, 0x3a58e94d, - /* 132 */ 0x98d220bc, 0xa351b8f7, 0xefd5102a, 0xd4568861, - /* 136 */ 0x71b18589, 0x4a321dc2, 0x06b6b51f, 0x3d352d54, - /* 140 */ 0x9fbfe4a5, 0xa43c7cee, 0xe8b8d433, 0xd33b4c78, - /* 144 */ 0x7807c9a2, 0x438451e9, 0x0f00f934, 0x3483617f, - /* 148 */ 0x9609a88e, 0xad8a30c5, 0xe10e9818, 0xda8d0053, - /* 152 */ 0x7f6a0dbb, 0x44e995f0, 0x086d3d2d, 0x33eea566, - /* 156 */ 0x91646c97, 0xaae7f4dc, 0xe6635c01, 0xdde0c44a, - /* 160 */ 0x6b6b51f4, 0x50e8c9bf, 0x1c6c6162, 0x27eff929, - /* 164 */ 0x856530d8, 0xbee6a893, 0xf262004e, 0xc9e19805, - /* 168 */ 0x6c0695ed, 0x57850da6, 0x1b01a57b, 0x20823d30, - /* 172 */ 0x8208f4c1, 0xb98b6c8a, 0xf50fc457, 0xce8c5c1c, - /* 176 */ 0x65b0d9c6, 0x5e33418d, 0x12b7e950, 0x2934711b, - /* 180 */ 0x8bbeb8ea, 0xb03d20a1, 0xfcb9887c, 0xc73a1037, - /* 184 */ 0x62dd1ddf, 0x595e8594, 0x15da2d49, 0x2e59b502, - /* 188 */ 0x8cd37cf3, 0xb750e4b8, 0xfbd44c65, 0xc057d42e, - /* 192 */ 0x4db26158, 0x7631f913, 0x3ab551ce, 0x0136c985, - /* 196 */ 0xa3bc0074, 0x983f983f, 0xd4bb30e2, 0xef38a8a9, - /* 200 */ 0x4adfa541, 0x715c3d0a, 0x3dd895d7, 0x065b0d9c, - /* 204 */ 0xa4d1c46d, 0x9f525c26, 0xd3d6f4fb, 0xe8556cb0, - /* 208 */ 0x4369e96a, 0x78ea7121, 0x346ed9fc, 0x0fed41b7, - /* 212 */ 0xad678846, 0x96e4100d, 0xda60b8d0, 0xe1e3209b, - /* 216 */ 0x44042d73, 0x7f87b538, 0x33031de5, 0x088085ae, - /* 220 */ 0xaa0a4c5f, 0x9189d414, 0xdd0d7cc9, 0xe68ee482, - /* 224 */ 0x5005713c, 0x6b86e977, 0x270241aa, 0x1c81d9e1, - /* 228 */ 0xbe0b1010, 0x8588885b, 0xc90c2086, 0xf28fb8cd, - /* 232 */ 0x5768b525, 0x6ceb2d6e, 0x206f85b3, 0x1bec1df8, - /* 236 */ 0xb966d409, 0x82e54c42, 0xce61e49f, 0xf5e27cd4, - /* 240 */ 0x5edef90e, 0x655d6145, 0x29d9c998, 0x125a51d3, - /* 244 */ 0xb0d09822, 0x8b530069, 0xc7d7a8b4, 0xfc5430ff, - /* 248 */ 0x59b33d17, 0x6230a55c, 0x2eb40d81, 0x153795ca, - /* 252 */ 0xb7bd5c3b, 0x8c3ec470, 0xc0ba6cad, 0xfb39f4e6, + /* 0 */ 0x00000000, 0x3b83984b, 0x77073096, 0x4c84a8dd, + /* 4 */ 0xee0e612c, 0xd58df967, 0x990951ba, 0xa28ac9f1, + /* 8 */ 0x076dc419, 0x3cee5c52, 0x706af48f, 0x4be96cc4, + /* 12 */ 0xe963a535, 0xd2e03d7e, 0x9e6495a3, 0xa5e70de8, + /* 16 */ 0x0edb8832, 0x35581079, 0x79dcb8a4, 0x425f20ef, + /* 20 */ 0xe0d5e91e, 0xdb567155, 0x97d2d988, 0xac5141c3, + /* 24 */ 0x09b64c2b, 0x3235d460, 0x7eb17cbd, 0x4532e4f6, + /* 28 */ 0xe7b82d07, 0xdc3bb54c, 0x90bf1d91, 0xab3c85da, + /* 32 */ 0x1db71064, 0x2634882f, 0x6ab020f2, 0x5133b8b9, + /* 36 */ 0xf3b97148, 0xc83ae903, 0x84be41de, 0xbf3dd995, + /* 40 */ 0x1adad47d, 0x21594c36, 0x6ddde4eb, 0x565e7ca0, + /* 44 */ 0xf4d4b551, 0xcf572d1a, 0x83d385c7, 0xb8501d8c, + /* 48 */ 0x136c9856, 0x28ef001d, 0x646ba8c0, 0x5fe8308b, + /* 52 */ 0xfd62f97a, 0xc6e16131, 0x8a65c9ec, 0xb1e651a7, + /* 56 */ 0x14015c4f, 0x2f82c404, 0x63066cd9, 0x5885f492, + /* 60 */ 0xfa0f3d63, 0xc18ca528, 0x8d080df5, 0xb68b95be, + /* 64 */ 0x3b6e20c8, 0x00edb883, 0x4c69105e, 0x77ea8815, + /* 68 */ 0xd56041e4, 0xeee3d9af, 0xa2677172, 0x99e4e939, + /* 72 */ 0x3c03e4d1, 0x07807c9a, 0x4b04d447, 0x70874c0c, + /* 76 */ 0xd20d85fd, 0xe98e1db6, 0xa50ab56b, 0x9e892d20, + /* 80 */ 0x35b5a8fa, 0x0e3630b1, 0x42b2986c, 0x79310027, + /* 84 */ 0xdbbbc9d6, 0xe038519d, 0xacbcf940, 0x973f610b, + /* 88 */ 0x32d86ce3, 0x095bf4a8, 0x45df5c75, 0x7e5cc43e, + /* 92 */ 0xdcd60dcf, 0xe7559584, 0xabd13d59, 0x9052a512, + /* 96 */ 0x26d930ac, 0x1d5aa8e7, 0x51de003a, 0x6a5d9871, + /* 100 */ 0xc8d75180, 0xf354c9cb, 0xbfd06116, 0x8453f95d, + /* 104 */ 0x21b4f4b5, 0x1a376cfe, 0x56b3c423, 0x6d305c68, + /* 108 */ 0xcfba9599, 0xf4390dd2, 0xb8bda50f, 0x833e3d44, + /* 112 */ 0x2802b89e, 0x138120d5, 0x5f058808, 0x64861043, + /* 116 */ 0xc60cd9b2, 0xfd8f41f9, 0xb10be924, 0x8a88716f, + /* 120 */ 0x2f6f7c87, 0x14ece4cc, 0x58684c11, 0x63ebd45a, + /* 124 */ 0xc1611dab, 0xfae285e0, 0xb6662d3d, 0x8de5b576, + /* 128 */ 0x76dc4190, 0x4d5fd9db, 0x01db7106, 0x3a58e94d, + /* 132 */ 0x98d220bc, 0xa351b8f7, 0xefd5102a, 0xd4568861, + /* 136 */ 0x71b18589, 0x4a321dc2, 0x06b6b51f, 0x3d352d54, + /* 140 */ 0x9fbfe4a5, 0xa43c7cee, 0xe8b8d433, 0xd33b4c78, + /* 144 */ 0x7807c9a2, 0x438451e9, 0x0f00f934, 0x3483617f, + /* 148 */ 0x9609a88e, 0xad8a30c5, 0xe10e9818, 0xda8d0053, + /* 152 */ 0x7f6a0dbb, 0x44e995f0, 0x086d3d2d, 0x33eea566, + /* 156 */ 0x91646c97, 0xaae7f4dc, 0xe6635c01, 0xdde0c44a, + /* 160 */ 0x6b6b51f4, 0x50e8c9bf, 0x1c6c6162, 0x27eff929, + /* 164 */ 0x856530d8, 0xbee6a893, 0xf262004e, 0xc9e19805, + /* 168 */ 0x6c0695ed, 0x57850da6, 0x1b01a57b, 0x20823d30, + /* 172 */ 0x8208f4c1, 0xb98b6c8a, 0xf50fc457, 0xce8c5c1c, + /* 176 */ 0x65b0d9c6, 0x5e33418d, 0x12b7e950, 0x2934711b, + /* 180 */ 0x8bbeb8ea, 0xb03d20a1, 0xfcb9887c, 0xc73a1037, + /* 184 */ 0x62dd1ddf, 0x595e8594, 0x15da2d49, 0x2e59b502, + /* 188 */ 0x8cd37cf3, 0xb750e4b8, 0xfbd44c65, 0xc057d42e, + /* 192 */ 0x4db26158, 0x7631f913, 0x3ab551ce, 0x0136c985, + /* 196 */ 0xa3bc0074, 0x983f983f, 0xd4bb30e2, 0xef38a8a9, + /* 200 */ 0x4adfa541, 0x715c3d0a, 0x3dd895d7, 0x065b0d9c, + /* 204 */ 0xa4d1c46d, 0x9f525c26, 0xd3d6f4fb, 0xe8556cb0, + /* 208 */ 0x4369e96a, 0x78ea7121, 0x346ed9fc, 0x0fed41b7, + /* 212 */ 0xad678846, 0x96e4100d, 0xda60b8d0, 0xe1e3209b, + /* 216 */ 0x44042d73, 0x7f87b538, 0x33031de5, 0x088085ae, + /* 220 */ 0xaa0a4c5f, 0x9189d414, 0xdd0d7cc9, 0xe68ee482, + /* 224 */ 0x5005713c, 0x6b86e977, 0x270241aa, 0x1c81d9e1, + /* 228 */ 0xbe0b1010, 0x8588885b, 0xc90c2086, 0xf28fb8cd, + /* 232 */ 0x5768b525, 0x6ceb2d6e, 0x206f85b3, 0x1bec1df8, + /* 236 */ 0xb966d409, 0x82e54c42, 0xce61e49f, 0xf5e27cd4, + /* 240 */ 0x5edef90e, 0x655d6145, 0x29d9c998, 0x125a51d3, + /* 244 */ 0xb0d09822, 0x8b530069, 0xc7d7a8b4, 0xfc5430ff, + /* 248 */ 0x59b33d17, 0x6230a55c, 0x2eb40d81, 0x153795ca, + /* 252 */ 0xb7bd5c3b, 0x8c3ec470, 0xc0ba6cad, 0xfb39f4e6, }; -unsigned int apc_crc32(const unsigned char* buf, unsigned int len) +unsigned int +apc_crc32(const unsigned char* buf, unsigned int len) { unsigned int i; int k; @@ -320,21 +334,24 @@ unsigned int apc_crc32(const unsigned char* buf, unsigned int len) } /* }}} */ /* {{{ apc_flip_hash */ -HashTable* apc_flip_hash(HashTable *hash) { +HashTable* +apc_flip_hash(HashTable* hash) +{ zval data, *entry; - HashTable *new_hash; + HashTable* new_hash; HashPosition pos; - if(hash == NULL) return hash; + if (hash == NULL) + return hash; ZVAL_LONG(&data, 1); - + ALLOC_HASHTABLE(new_hash); zend_hash_init(new_hash, zend_hash_num_elements(hash), NULL, ZVAL_PTR_DTOR, 0); zend_hash_internal_pointer_reset_ex(hash, &pos); while ((entry = zend_hash_get_current_data_ex(hash, &pos)) != NULL) { - if(Z_TYPE_P(entry) == IS_STRING) { + if (Z_TYPE_P(entry) == IS_STRING) { zend_hash_update(new_hash, Z_STR_P(entry), &data); } else { zend_hash_index_update(new_hash, Z_LVAL_P(entry), &data); @@ -354,27 +371,28 @@ HashTable* apc_flip_hash(HashTable *hash) { #define APC_MAX_SERIALIZERS 16 /* pointer to the list of serializers */ -static apc_serializer_t apc_serializers[APC_MAX_SERIALIZERS] = {{0,}}; +static apc_serializer_t apc_serializers[APC_MAX_SERIALIZERS] = { { + 0, +} }; /* }}} */ /* {{{ apc_register_serializer */ -PHP_APCU_API int _apc_register_serializer(const char* name, - apc_serialize_t serialize, - apc_unserialize_t unserialize, - void *config) { +PHP_APCU_API int +_apc_register_serializer(const char* name, apc_serialize_t serialize, apc_unserialize_t unserialize, void* config) +{ int i; - apc_serializer_t *serializer; + apc_serializer_t* serializer; - for(i = 0; i < APC_MAX_SERIALIZERS; i++) { + for (i = 0; i < APC_MAX_SERIALIZERS; i++) { serializer = &apc_serializers[i]; - if(!serializer->name) { + if (!serializer->name) { /* empty entry */ - serializer->name = name; - serializer->serialize = serialize; + serializer->name = name; + serializer->serialize = serialize; serializer->unserialize = unserialize; - serializer->config = config; + serializer->config = config; if (i < APC_MAX_SERIALIZERS - 1) { - apc_serializers[i+1].name = NULL; + apc_serializers[i + 1].name = NULL; } return 1; } @@ -384,18 +402,22 @@ PHP_APCU_API int _apc_register_serializer(const char* name, } /* }}} */ /* {{{ apc_get_serializers */ -PHP_APCU_API apc_serializer_t* apc_get_serializers() { - return &(apc_serializers[0]); +PHP_APCU_API apc_serializer_t* +apc_get_serializers() +{ + return &(apc_serializers[0]); } /* }}} */ /* {{{ apc_find_serializer */ -PHP_APCU_API apc_serializer_t* apc_find_serializer(const char* name) { - int i; - apc_serializer_t *serializer; +PHP_APCU_API apc_serializer_t* +apc_find_serializer(const char* name) +{ + int i; + apc_serializer_t* serializer; - for(i = 0; i < APC_MAX_SERIALIZERS; i++) { + for (i = 0; i < APC_MAX_SERIALIZERS; i++) { serializer = &apc_serializers[i]; - if(serializer->name && (strcmp(serializer->name, name) == 0)) { + if (serializer->name && (strcmp(serializer->name, name) == 0)) { return serializer; } } diff --git a/apc.h b/apc.h index abd72824..0be4dfe1 100644 --- a/apc.h +++ b/apc.h @@ -38,11 +38,11 @@ * This module defines utilities and helper functions used elsewhere in APC. */ #ifdef PHP_WIN32 -# define PHP_APCU_API __declspec(dllexport) +#define PHP_APCU_API __declspec(dllexport) #elif defined(__GNUC__) && __GNUC__ >= 4 -# define PHP_APCU_API __attribute__ ((visibility("default"))) +#define PHP_APCU_API __attribute__((visibility("default"))) #else -# define PHP_APCU_API +#define PHP_APCU_API #endif /* Commonly needed C library headers. */ @@ -71,23 +71,23 @@ /* typedefs for extensible memory allocators */ typedef void* (*apc_malloc_t)(size_t); -typedef void (*apc_free_t) (void *); +typedef void (*apc_free_t)(void*); /* wrappers for memory allocation routines */ PHP_APCU_API void* apc_emalloc(size_t n); PHP_APCU_API void* apc_erealloc(void* p, size_t n); PHP_APCU_API void* apc_php_malloc(size_t n); -PHP_APCU_API void apc_php_free(void* p); -PHP_APCU_API void apc_efree(void* p); +PHP_APCU_API void apc_php_free(void* p); +PHP_APCU_API void apc_efree(void* p); PHP_APCU_API char* apc_estrdup(const char* s); PHP_APCU_API void* apc_xstrdup(const char* s, apc_malloc_t f); PHP_APCU_API void* apc_xmemcpy(const void* p, size_t n, apc_malloc_t f); /* console display functions */ -PHP_APCU_API void apc_error(const char *format, ...); -PHP_APCU_API void apc_warning(const char *format, ...); -PHP_APCU_API void apc_notice(const char *format, ...); -PHP_APCU_API void apc_debug(const char *format, ...); +PHP_APCU_API void apc_error(const char* format, ...); +PHP_APCU_API void apc_warning(const char* format, ...); +PHP_APCU_API void apc_notice(const char* format, ...); +PHP_APCU_API void apc_debug(const char* format, ...); /* string and text manipulation */ PHP_APCU_API char* apc_append(const char* s, const char* t); @@ -98,28 +98,27 @@ PHP_APCU_API char** apc_tokenize(const char* s, char delim); PHP_APCU_API unsigned int apc_crc32(const unsigned char* buf, unsigned int len); /* apc_flip_hash flips keys and values for faster searching */ -PHP_APCU_API HashTable* apc_flip_hash(HashTable *hash); +PHP_APCU_API HashTable* apc_flip_hash(HashTable* hash); #define APC_NEGATIVE_MATCH 1 #define APC_POSITIVE_MATCH 2 -#define apc_time() \ - (APCG(use_request_time) ? (time_t) sapi_get_request_time() : time(0)) +#define apc_time() (APCG(use_request_time) ? (time_t) sapi_get_request_time() : time(0)) #if defined(__GNUC__) -# define APC_UNUSED __attribute__((unused)) -# define APC_USED __attribute__((used)) -# define APC_ALLOC __attribute__((malloc)) -# if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 2) -# define APC_HOTSPOT __attribute__((hot)) -# else -# define APC_HOTSPOT -# endif -#else -# define APC_UNUSED -# define APC_USED -# define APC_ALLOC -# define APC_HOTSPOT +#define APC_UNUSED __attribute__((unused)) +#define APC_USED __attribute__((used)) +#define APC_ALLOC __attribute__((malloc)) +#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 2) +#define APC_HOTSPOT __attribute__((hot)) +#else +#define APC_HOTSPOT +#endif +#else +#define APC_UNUSED +#define APC_USED +#define APC_ALLOC +#define APC_HOTSPOT #endif /* @@ -139,21 +138,21 @@ typedef int (*apc_unserialize_t)(APC_UNSERIALIZER_ARGS); /* {{{ struct definition: apc_serializer_t */ typedef struct apc_serializer_t { - const char* name; - apc_serialize_t serialize; - apc_unserialize_t unserialize; - void* config; + const char* name; + apc_serialize_t serialize; + apc_unserialize_t unserialize; + void* config; } apc_serializer_t; /* }}} */ /* {{{ _apc_register_serializer registers the serializer using the given name and paramters */ PHP_APCU_API int _apc_register_serializer(const char* name, - apc_serialize_t serialize, - apc_unserialize_t unserialize, - void *config); /* }}} */ + apc_serialize_t serialize, + apc_unserialize_t unserialize, + void* config); /* }}} */ -/* {{{ apc_get_serializers +/* {{{ apc_get_serializers fetches the list of serializers */ PHP_APCU_API apc_serializer_t* apc_get_serializers(); /* }}} */ @@ -162,35 +161,37 @@ PHP_APCU_API apc_serializer_t* apc_get_serializers(); /* }}} */ PHP_APCU_API apc_serializer_t* apc_find_serializer(const char* name); /* }}} */ /* {{{ default serializers */ -PHP_APCU_API int APC_SERIALIZER_NAME(php) (APC_SERIALIZER_ARGS); -PHP_APCU_API int APC_UNSERIALIZER_NAME(php) (APC_UNSERIALIZER_ARGS); /* }}} */ +PHP_APCU_API int APC_SERIALIZER_NAME(php)(APC_SERIALIZER_ARGS); +PHP_APCU_API int APC_UNSERIALIZER_NAME(php)(APC_UNSERIALIZER_ARGS); /* }}} */ /* {{{ eval serializers */ -PHP_APCU_API int APC_SERIALIZER_NAME(eval) (APC_SERIALIZER_ARGS); -PHP_APCU_API int APC_UNSERIALIZER_NAME(eval) (APC_UNSERIALIZER_ARGS); /* }}} */ - -#define php_apc_try(begin, block, end) { \ - JMP_BUF *zb = EG(bailout); \ - JMP_BUF ab; \ - \ - EG(bailout) = &ab; \ - \ - begin; \ - if (SETJMP(ab) == SUCCESS) { \ - block \ - } else { \ - end; \ - EG(bailout) = zb; \ - zend_bailout(); \ - } \ - end; \ - EG(bailout) = zb; \ -} - -#define php_apc_try_end(early) { \ - EG(bailout) = zb; \ - early \ -} +PHP_APCU_API int APC_SERIALIZER_NAME(eval)(APC_SERIALIZER_ARGS); +PHP_APCU_API int APC_UNSERIALIZER_NAME(eval)(APC_UNSERIALIZER_ARGS); /* }}} */ + +#define php_apc_try(begin, block, end) \ + { \ + JMP_BUF* zb = EG(bailout); \ + JMP_BUF ab; \ + \ + EG(bailout) = &ab; \ + \ + begin; \ + if (SETJMP(ab) == SUCCESS) { \ + block \ + } else { \ + end; \ + EG(bailout) = zb; \ + zend_bailout(); \ + } \ + end; \ + EG(bailout) = zb; \ + } + +#define php_apc_try_end(early) \ + { \ + EG(bailout) = zb; \ + early \ + } #endif diff --git a/apc_arginfo.h b/apc_arginfo.h index 6cf57400..799ca4c8 100644 --- a/apc_arginfo.h +++ b/apc_arginfo.h @@ -22,58 +22,58 @@ /* {{{ arginfo */ ZEND_BEGIN_ARG_INFO_EX(arginfo_apcu_store, 0, 0, 2) - ZEND_ARG_INFO(0, key) - ZEND_ARG_INFO(0, var) - ZEND_ARG_INFO(0, ttl) +ZEND_ARG_INFO(0, key) +ZEND_ARG_INFO(0, var) +ZEND_ARG_INFO(0, ttl) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO_EX(arginfo_apcu_enabled, 0, 0, 0) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO_EX(arginfo_apcu_cache_info, 0, 0, 0) - ZEND_ARG_INFO(0, limited) +ZEND_ARG_INFO(0, limited) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO_EX(arginfo_apcu_clear_cache, 0, 0, 0) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO_EX(arginfo_apcu_key_info, 0, 0, 1) - ZEND_ARG_INFO(0, key) +ZEND_ARG_INFO(0, key) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO_EX(arginfo_apcu_sma_info, 0, 0, 0) - ZEND_ARG_INFO(0, limited) +ZEND_ARG_INFO(0, limited) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO(arginfo_apcu_delete, 0) - ZEND_ARG_INFO(0, keys) +ZEND_ARG_INFO(0, keys) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO_EX(arginfo_apcu_fetch, 0, 0, 1) - ZEND_ARG_INFO(0, key) - ZEND_ARG_INFO(1, success) +ZEND_ARG_INFO(0, key) +ZEND_ARG_INFO(1, success) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO_EX(arginfo_apcu_inc, 0, 0, 1) - ZEND_ARG_INFO(0, key) - ZEND_ARG_INFO(0, step) - ZEND_ARG_INFO(1, success) +ZEND_ARG_INFO(0, key) +ZEND_ARG_INFO(0, step) +ZEND_ARG_INFO(1, success) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO(arginfo_apcu_cas, 0) - ZEND_ARG_INFO(0, key) - ZEND_ARG_INFO(0, old) - ZEND_ARG_INFO(0, new) +ZEND_ARG_INFO(0, key) +ZEND_ARG_INFO(0, old) +ZEND_ARG_INFO(0, new) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO(arginfo_apcu_exists, 0) - ZEND_ARG_INFO(0, keys) +ZEND_ARG_INFO(0, keys) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO_EX(arginfo_apcu_entry, 0, 0, 2) - ZEND_ARG_INFO(0, key) - ZEND_ARG_TYPE_INFO(0, generator, IS_CALLABLE, 0) - ZEND_ARG_TYPE_INFO(0, ttl, IS_LONG, 0) +ZEND_ARG_INFO(0, key) +ZEND_ARG_TYPE_INFO(0, generator, IS_CALLABLE, 0) +ZEND_ARG_TYPE_INFO(0, ttl, IS_LONG, 0) ZEND_END_ARG_INFO() /* }}} */ diff --git a/apc_cache.c b/apc_cache.c index ac90baad..b0e35b8f 100644 --- a/apc_cache.c +++ b/apc_cache.c @@ -44,218 +44,223 @@ typedef void* (*ht_copy_fun_t)(void*, void*, apc_context_t*); typedef int (*ht_check_copy_fun_t)(Bucket*, va_list); -#define CHECK(p) { if ((p) == NULL) return NULL; } +#define CHECK(p) \ + { \ + if ((p) == NULL) \ + return NULL; \ + } static APC_HOTSPOT zval* my_copy_zval(zval* dst, const zval* src, apc_context_t* ctxt); /* {{{ make_prime */ static int const primes[] = { - 257, /* 256 */ - 521, /* 512 */ - 1031, /* 1024 */ - 2053, /* 2048 */ - 3079, /* 3072 */ - 4099, /* 4096 */ - 5147, /* 5120 */ - 6151, /* 6144 */ - 7177, /* 7168 */ - 8209, /* 8192 */ - 9221, /* 9216 */ -10243, /* 10240 */ -11273, /* 11264 */ -12289, /* 12288 */ -13313, /* 13312 */ -14341, /* 14336 */ -15361, /* 15360 */ -16411, /* 16384 */ -17417, /* 17408 */ -18433, /* 18432 */ -19457, /* 19456 */ -20483, /* 20480 */ -30727, /* 30720 */ -40961, /* 40960 */ -61441, /* 61440 */ -81929, /* 81920 */ -122887,/* 122880 */ -163841,/* 163840 */ -245771,/* 245760 */ -327689,/* 327680 */ -491527,/* 491520 */ -655373,/* 655360 */ -983063,/* 983040 */ -0 /* sentinel */ + 257, /* 256 */ + 521, /* 512 */ + 1031, /* 1024 */ + 2053, /* 2048 */ + 3079, /* 3072 */ + 4099, /* 4096 */ + 5147, /* 5120 */ + 6151, /* 6144 */ + 7177, /* 7168 */ + 8209, /* 8192 */ + 9221, /* 9216 */ + 10243, /* 10240 */ + 11273, /* 11264 */ + 12289, /* 12288 */ + 13313, /* 13312 */ + 14341, /* 14336 */ + 15361, /* 15360 */ + 16411, /* 16384 */ + 17417, /* 17408 */ + 18433, /* 18432 */ + 19457, /* 19456 */ + 20483, /* 20480 */ + 30727, /* 30720 */ + 40961, /* 40960 */ + 61441, /* 61440 */ + 81929, /* 81920 */ + 122887, /* 122880 */ + 163841, /* 163840 */ + 245771, /* 245760 */ + 327689, /* 327680 */ + 491527, /* 491520 */ + 655373, /* 655360 */ + 983063, /* 983040 */ + 0 /* sentinel */ }; -static int make_prime(int n) +static int +make_prime(int n) { - int *k = (int*)primes; - while(*k) { - if((*k) > n) return *k; + int* k = (int*) primes; + while (*k) { + if ((*k) > n) + return *k; k++; } - return *(k-1); + return *(k - 1); } /* }}} */ /* {{{ make_slot */ -apc_cache_slot_t* make_slot(apc_cache_t* cache, apc_cache_key_t *key, apc_cache_entry_t* value, apc_cache_slot_t* next, time_t t) +apc_cache_slot_t* +make_slot(apc_cache_t* cache, apc_cache_key_t* key, apc_cache_entry_t* value, apc_cache_slot_t* next, time_t t) { - apc_cache_slot_t* p = NULL; - - /* allocate slot */ - if ((p = value->pool->palloc(value->pool, sizeof(apc_cache_slot_t)))) { - - /* copy identifier */ - zend_string *copiedKey = apc_pstrcpy(key->str, value->pool); - - if (copiedKey == NULL) { + apc_cache_slot_t* p = NULL; + + /* allocate slot */ + if ((p = value->pool->palloc(value->pool, sizeof(apc_cache_slot_t)))) { + + /* copy identifier */ + zend_string* copiedKey = apc_pstrcpy(key->str, value->pool); + + if (copiedKey == NULL) { value->pool->pfree(value->pool, p); return NULL; } - - /* set slot data */ - p->key = key[0]; - p->key.str = copiedKey; - p->value = value; - - /* set slot relation */ - p->next = next; - - /* set slot defaults */ - p->nhits = 0; - p->ctime = t; - p->atime = t; - p->dtime = 0; - } + + /* set slot data */ + p->key = key[0]; + p->key.str = copiedKey; + p->value = value; + + /* set slot relation */ + p->next = next; + + /* set slot defaults */ + p->nhits = 0; + p->ctime = t; + p->atime = t; + p->dtime = 0; + } return p; } /* }}} */ /* {{{ free_slot */ -static void free_slot(apc_cache_slot_t* slot) +static void +free_slot(apc_cache_slot_t* slot) { - /* destroy slot pool */ - apc_pool_destroy( - slot->value->pool); + /* destroy slot pool */ + apc_pool_destroy(slot->value->pool); } /* }}} */ /* {{{ apc_cache_hash_slot Note: These calculations can and should be done outside of a lock */ -static void apc_cache_hash_slot(apc_cache_t* cache, - zend_string *key, - zend_ulong* hash, - zend_ulong* slot) { - (*hash) = ZSTR_HASH(key); - (*slot) = (*hash) % (cache->nslots); +static void +apc_cache_hash_slot(apc_cache_t* cache, zend_string* key, zend_ulong* hash, zend_ulong* slot) +{ + (*hash) = ZSTR_HASH(key); + (*slot) = (*hash) % (cache->nslots); } /* }}} */ /* {{{ apc_cache_remove_slot */ -PHP_APCU_API void apc_cache_remove_slot(apc_cache_t* cache, apc_cache_slot_t** slot) +PHP_APCU_API void +apc_cache_remove_slot(apc_cache_t* cache, apc_cache_slot_t** slot) { apc_cache_slot_t* dead = *slot; - + /* think here is safer */ - *slot = (*slot)->next; + *slot = (*slot)->next; - /* adjust header info */ - if (cache->header->mem_size) - cache->header->mem_size -= dead->value->mem_size; + /* adjust header info */ + if (cache->header->mem_size) + cache->header->mem_size -= dead->value->mem_size; if (cache->header->nentries) - cache->header->nentries--; - - /* remove if there are no references */ + cache->header->nentries--; + + /* remove if there are no references */ if (dead->value->ref_count <= 0) { free_slot(dead); } else { - /* add to gc if there are still refs */ - dead->next = cache->header->gc; - dead->dtime = time(0); + /* add to gc if there are still refs */ + dead->next = cache->header->gc; + dead->dtime = time(0); cache->header->gc = dead; } } /* }}} */ /* {{{ apc_cache_gc */ -PHP_APCU_API void apc_cache_gc(apc_cache_t* cache) +PHP_APCU_API void +apc_cache_gc(apc_cache_t* cache) { /* This function scans the list of removed cache entries and deletes any - * entry whose reference count is zero or that has been on the gc - * list for more than cache->gc_ttl seconds - * (we issue a warning in the latter case). + * entry whose reference count is zero or that has been on the gc + * list for more than cache->gc_ttl seconds + * (we issue a warning in the latter case). */ - if (!cache || !cache->header->gc) { - return; - } + if (!cache || !cache->header->gc) { + return; + } { - apc_cache_slot_t** slot = &cache->header->gc; + apc_cache_slot_t** slot = &cache->header->gc; - while (*slot != NULL) { - time_t now = time(0); - time_t gc_sec = cache->gc_ttl ? (now - (*slot)->dtime) : 0; + while (*slot != NULL) { + time_t now = time(0); + time_t gc_sec = cache->gc_ttl ? (now - (*slot)->dtime) : 0; - if (!(*slot)->value->ref_count || gc_sec > (time_t)cache->gc_ttl) { + if (!(*slot)->value->ref_count || gc_sec > (time_t) cache->gc_ttl) { apc_cache_slot_t* dead = *slot; - /* good ol' whining */ - if (dead->value->ref_count > 0) { - apc_debug( - "GC cache entry '%s' was on gc-list for %d seconds", - dead->key.str, gc_sec - ); - } - - /* set next slot */ - *slot = dead->next; - - /* free slot */ - free_slot( - dead); - - /* next */ - continue; - - } else { - slot = &(*slot)->next; - } - } - } + /* good ol' whining */ + if (dead->value->ref_count > 0) { + apc_debug("GC cache entry '%s' was on gc-list for %d seconds", dead->key.str, gc_sec); + } + + /* set next slot */ + *slot = dead->next; + + /* free slot */ + free_slot(dead); + + /* next */ + continue; + + } else { + slot = &(*slot)->next; + } + } + } } /* }}} */ /* {{{ php serializer */ -PHP_APCU_API int APC_SERIALIZER_NAME(php) (APC_SERIALIZER_ARGS) +PHP_APCU_API int APC_SERIALIZER_NAME(php)(APC_SERIALIZER_ARGS) { - smart_str strbuf = {0}; + smart_str strbuf = { 0 }; php_serialize_data_t var_hash; PHP_VAR_SERIALIZE_INIT(var_hash); php_var_serialize(&strbuf, (zval*) value, &var_hash); PHP_VAR_SERIALIZE_DESTROY(var_hash); if (strbuf.s != NULL) { - *buf = (unsigned char *)estrndup(ZSTR_VAL(strbuf.s), ZSTR_LEN(strbuf.s)); + *buf = (unsigned char*) estrndup(ZSTR_VAL(strbuf.s), ZSTR_LEN(strbuf.s)); if (*buf == NULL) return 0; *buf_len = ZSTR_LEN(strbuf.s); - smart_str_free(&strbuf); + smart_str_free(&strbuf); return 1; } return 0; } /* }}} */ /* {{{ php unserializer */ -PHP_APCU_API int APC_UNSERIALIZER_NAME(php) (APC_UNSERIALIZER_ARGS) +PHP_APCU_API int APC_UNSERIALIZER_NAME(php)(APC_UNSERIALIZER_ARGS) { - const unsigned char *tmp = buf; + const unsigned char* tmp = buf; php_unserialize_data_t var_hash; PHP_VAR_UNSERIALIZE_INIT(var_hash); - if(!php_var_unserialize(value, &tmp, buf + buf_len, &var_hash)) { + if (!php_var_unserialize(value, &tmp, buf + buf_len, &var_hash)) { PHP_VAR_UNSERIALIZE_DESTROY(var_hash); - php_error_docref(NULL, E_NOTICE, "Error at offset %ld of %ld bytes", (zend_long)(tmp - buf), (zend_long)buf_len); + php_error_docref(NULL, E_NOTICE, "Error at offset %ld of %ld bytes", (zend_long)(tmp - buf), + (zend_long) buf_len); ZVAL_NULL(value); return 0; } @@ -264,157 +269,174 @@ PHP_APCU_API int APC_UNSERIALIZER_NAME(php) (APC_UNSERIALIZER_ARGS) } /* }}} */ /* {{{ apc_cache_create */ -PHP_APCU_API apc_cache_t* apc_cache_create(apc_sma_t* sma, apc_serializer_t* serializer, zend_long size_hint, zend_long gc_ttl, zend_long ttl, zend_long smart, zend_bool defend) { - apc_cache_t* cache; +PHP_APCU_API apc_cache_t* +apc_cache_create(apc_sma_t* sma, + apc_serializer_t* serializer, + zend_long size_hint, + zend_long gc_ttl, + zend_long ttl, + zend_long smart, + zend_bool defend) +{ + apc_cache_t* cache; zend_long cache_size; zend_long nslots; - /* calculate number of slots */ + /* calculate number of slots */ nslots = make_prime(size_hint > 0 ? size_hint : 2000); - /* allocate pointer by normal means */ + /* allocate pointer by normal means */ cache = (apc_cache_t*) apc_emalloc(sizeof(apc_cache_t)); if (!cache) { apc_error("Unable to allocate memory for cache structures. (Perhaps your memory_limit isn't large enough?). "); return NULL; } - - /* calculate cache size for shm allocation */ - cache_size = sizeof(apc_cache_header_t) + nslots*sizeof(apc_cache_slot_t*); - /* allocate shm */ + /* calculate cache size for shm allocation */ + cache_size = sizeof(apc_cache_header_t) + nslots * sizeof(apc_cache_slot_t*); + + /* allocate shm */ cache->shmaddr = sma->smalloc(cache_size); - if(!cache->shmaddr) { - apc_error("Unable to allocate shared memory for cache structures. (Perhaps your shared memory size isn't large enough?). "); + if (!cache->shmaddr) { + apc_error( + "Unable to allocate shared memory for cache structures. (Perhaps your shared memory size isn't large " + "enough?). "); return NULL; } - - /* zero shm */ + + /* zero shm */ memset(cache->shmaddr, 0, cache_size); - /* set default header */ + /* set default header */ cache->header = (apc_cache_header_t*) cache->shmaddr; - - cache->header->nhits = 0; - cache->header->nmisses = 0; - cache->header->nentries = 0; + + cache->header->nhits = 0; + cache->header->nmisses = 0; + cache->header->nentries = 0; cache->header->nexpunges = 0; - cache->header->gc = NULL; - cache->header->stime = time(NULL); - cache->header->state |= APC_CACHE_ST_NONE; - - /* set cache options */ - cache->slots = (apc_cache_slot_t**) (((char*) cache->shmaddr) + sizeof(apc_cache_header_t)); - cache->sma = sma; - cache->serializer = serializer; - cache->nslots = nslots; - cache->gc_ttl = gc_ttl; - cache->ttl = ttl; - cache->smart = smart; - cache->defend = defend; - - /* header lock */ - CREATE_LOCK(&cache->header->lock); - - /* zero slots */ - memset(cache->slots, 0, sizeof(apc_cache_slot_t*)*nslots); + cache->header->gc = NULL; + cache->header->stime = time(NULL); + cache->header->state |= APC_CACHE_ST_NONE; + + /* set cache options */ + cache->slots = (apc_cache_slot_t**) (((char*) cache->shmaddr) + sizeof(apc_cache_header_t)); + cache->sma = sma; + cache->serializer = serializer; + cache->nslots = nslots; + cache->gc_ttl = gc_ttl; + cache->ttl = ttl; + cache->smart = smart; + cache->defend = defend; + + /* header lock */ + CREATE_LOCK(&cache->header->lock); + + /* zero slots */ + memset(cache->slots, 0, sizeof(apc_cache_slot_t*) * nslots); return cache; } /* }}} */ -static inline zend_bool apc_cache_insert_internal(apc_cache_t* cache, - apc_cache_key_t *key, - apc_cache_entry_t* value, - apc_context_t* ctxt, - time_t t, - zend_bool exclusive) { - /* at least */ - if (!value) { - return 0; - } - - /* check we are able to deal with this request */ - if (!cache || apc_cache_busy(cache)) { - return 0; - } - - /* process deleted list */ +static inline zend_bool +apc_cache_insert_internal(apc_cache_t* cache, + apc_cache_key_t* key, + apc_cache_entry_t* value, + apc_context_t* ctxt, + time_t t, + zend_bool exclusive) +{ + /* at least */ + if (!value) { + return 0; + } + + /* check we are able to deal with this request */ + if (!cache || apc_cache_busy(cache)) { + return 0; + } + + /* process deleted list */ apc_cache_gc(cache); - /* make the insertion */ - { - apc_cache_slot_t** slot; - - /* - * select appropriate slot ... - */ - slot = &cache->slots[ZSTR_HASH(key->str) % cache->nslots]; - - while (*slot) { - - /* check for a match by hash and string */ - if ((ZSTR_HASH((*slot)->key.str) == ZSTR_HASH(key->str)) && - memcmp(ZSTR_VAL((*slot)->key.str), ZSTR_VAL(key->str), ZSTR_LEN(key->str)) == SUCCESS) { - - /* - * At this point we have found the user cache entry. If we are doing - * an exclusive insert (apc_add) we are going to bail right away if - * the user entry already exists and it has no ttl, or - * there is a ttl and the entry has not timed out yet. - */ - if(exclusive) { - if (!(*slot)->value->ttl || (time_t) ((*slot)->ctime + (*slot)->value->ttl) >= t) { + /* make the insertion */ + { + apc_cache_slot_t** slot; + + /* + * select appropriate slot ... + */ + slot = &cache->slots[ZSTR_HASH(key->str) % cache->nslots]; + + while (*slot) { + + /* check for a match by hash and string */ + if ((ZSTR_HASH((*slot)->key.str) == ZSTR_HASH(key->str)) && + memcmp(ZSTR_VAL((*slot)->key.str), ZSTR_VAL(key->str), ZSTR_LEN(key->str)) == SUCCESS) { + + /* + * At this point we have found the user cache entry. If we are doing + * an exclusive insert (apc_add) we are going to bail right away if + * the user entry already exists and it has no ttl, or + * there is a ttl and the entry has not timed out yet. + */ + if (exclusive) { + if (!(*slot)->value->ttl || (time_t)((*slot)->ctime + (*slot)->value->ttl) >= t) { return 0; } - } + } apc_cache_remove_slot(cache, slot); - break; - } else - - /* - * This is a bit nasty. The idea here is to do runtime cleanup of the linked list of - * slot entries so we don't always have to skip past a bunch of stale entries. We check - * for staleness here and get rid of them by first checking to see if the cache has a global - * access ttl on it and removing entries that haven't been accessed for ttl seconds and secondly - * we see if the entry has a hard ttl on it and remove it if it has been around longer than its ttl - */ - if((cache->ttl && (time_t)(*slot)->atime < (t - (time_t)cache->ttl)) || - ((*slot)->value->ttl && (time_t) ((*slot)->ctime + (*slot)->value->ttl) < t)) { + break; + } else + + /* + * This is a bit nasty. The idea here is to do runtime cleanup of the linked list of + * slot entries so we don't always have to skip past a bunch of stale entries. We check + * for staleness here and get rid of them by first checking to see if the cache has a global + * access ttl on it and removing entries that haven't been accessed for ttl seconds and secondly + * we see if the entry has a hard ttl on it and remove it if it has been around longer than its ttl + */ + if ((cache->ttl && (time_t)(*slot)->atime < (t - (time_t) cache->ttl)) || + ((*slot)->value->ttl && (time_t)((*slot)->ctime + (*slot)->value->ttl) < t)) { apc_cache_remove_slot(cache, slot); - continue; - } - - /* set next slot */ - slot = &(*slot)->next; - } - - if ((*slot = make_slot(cache, key, value, *slot, t)) != NULL) { + continue; + } + + /* set next slot */ + slot = &(*slot)->next; + } + + if ((*slot = make_slot(cache, key, value, *slot, t)) != NULL) { /* set value size from pool size */ value->mem_size = ctxt->pool->size; cache->header->mem_size += ctxt->pool->size; cache->header->nentries++; cache->header->ninserts++; - } else { - return 0; - } - } + } else { + return 0; + } + } return 1; } -static inline zend_bool apc_cache_store_internal(apc_cache_t *cache, zend_string *strkey, const zval *val, const int32_t ttl, const zend_bool exclusive) { - apc_cache_entry_t *entry; +static inline zend_bool +apc_cache_store_internal( + apc_cache_t* cache, zend_string* strkey, const zval* val, const int32_t ttl, const zend_bool exclusive) +{ + apc_cache_entry_t* entry; apc_cache_key_t key; time_t t; - apc_context_t ctxt={0,}; + apc_context_t ctxt = { + 0, + }; zend_bool ret = 0; t = apc_time(); - /* initialize a context suitable for making an insert */ + /* initialize a context suitable for making an insert */ if (apc_cache_make_context(cache, &ctxt, APC_CONTEXT_SHARE, APC_SMALL_POOL, APC_COPY_IN, 0)) { /* initialize the key for insertion */ @@ -422,10 +444,10 @@ static inline zend_bool apc_cache_store_internal(apc_cache_t *cache, zend_string /* run cache defense */ if (!apc_cache_defense(cache, &key)) { - + /* initialize the entry for insertion */ if ((entry = apc_cache_make_entry(&ctxt, &key, val, ttl))) { - + /* execute an insertion */ if (apc_cache_insert_internal(cache, &key, entry, &ctxt, t, exclusive)) { ret = 1; @@ -442,101 +464,111 @@ static inline zend_bool apc_cache_store_internal(apc_cache_t *cache, zend_string return ret; } -static inline apc_cache_entry_t* apc_cache_find_internal(apc_cache_t *cache, zend_string *key, time_t t, zend_bool lock) { - apc_cache_slot_t** slot; - zend_ulong h, s; +static inline apc_cache_entry_t* +apc_cache_find_internal(apc_cache_t* cache, zend_string* key, time_t t, zend_bool lock) +{ + apc_cache_slot_t** slot; + zend_ulong h, s; volatile apc_cache_entry_t* value = NULL; - if (lock) - APC_RLOCK(cache->header); - - /* calculate hash and slot */ - apc_cache_hash_slot(cache, key, &h, &s); + if (lock) + APC_RLOCK(cache->header); - /* find head */ - slot = &cache->slots[s]; + /* calculate hash and slot */ + apc_cache_hash_slot(cache, key, &h, &s); - while (*slot) { - /* check for a matching key by has and identifier */ - if ((h == ZSTR_HASH((*slot)->key.str)) && - memcmp(ZSTR_VAL((*slot)->key.str), ZSTR_VAL(key), ZSTR_LEN(key)) == SUCCESS) { + /* find head */ + slot = &cache->slots[s]; + + while (*slot) { + /* check for a matching key by has and identifier */ + if ((h == ZSTR_HASH((*slot)->key.str)) && + memcmp(ZSTR_VAL((*slot)->key.str), ZSTR_VAL(key), ZSTR_LEN(key)) == SUCCESS) { - /* Check to make sure this entry isn't expired by a hard TTL */ - if((*slot)->value->ttl && (time_t) ((*slot)->ctime + (*slot)->value->ttl) < t) { - /* increment misses on cache */ - ATOMIC_INC(cache, cache->header->nmisses); + /* Check to make sure this entry isn't expired by a hard TTL */ + if ((*slot)->value->ttl && (time_t)((*slot)->ctime + (*slot)->value->ttl) < t) { + /* increment misses on cache */ + ATOMIC_INC(cache, cache->header->nmisses); - if (lock) - APC_RUNLOCK(cache->header); - return NULL; - } - - /* set cache num hits */ - ATOMIC_INC(cache, cache->header->nhits); + if (lock) + APC_RUNLOCK(cache->header); + return NULL; + } - /* grab value */ - value = (*slot)->value; + /* set cache num hits */ + ATOMIC_INC(cache, cache->header->nhits); - (*slot)->atime = t; + /* grab value */ + value = (*slot)->value; - /* Otherwise we are fine, increase counters and return the cache entry */ - ATOMIC_INC(cache, (*slot)->nhits); - ATOMIC_INC(cache, (*slot)->value->ref_count); + (*slot)->atime = t; - if (lock) - APC_RUNLOCK(cache->header); + /* Otherwise we are fine, increase counters and return the cache entry */ + ATOMIC_INC(cache, (*slot)->nhits); + ATOMIC_INC(cache, (*slot)->value->ref_count); - return (apc_cache_entry_t*)value; - } + if (lock) + APC_RUNLOCK(cache->header); + + return (apc_cache_entry_t*) value; + } - /* next */ - slot = &(*slot)->next; - } + /* next */ + slot = &(*slot)->next; + } - /* not found, so increment misses */ - ATOMIC_INC(cache, cache->header->nmisses); + /* not found, so increment misses */ + ATOMIC_INC(cache, cache->header->nmisses); - if (lock) - APC_RUNLOCK(cache->header); + if (lock) + APC_RUNLOCK(cache->header); - return NULL; + return NULL; } -static inline zend_bool apc_cache_fetch_internal(apc_cache_t* cache, zend_string *key, apc_cache_entry_t *entry, time_t t, zval **dst) { - /* context for copying out */ - apc_context_t ctxt = {0, }; - zval *rv; +static inline zend_bool +apc_cache_fetch_internal(apc_cache_t* cache, zend_string* key, apc_cache_entry_t* entry, time_t t, zval** dst) +{ + /* context for copying out */ + apc_context_t ctxt = { + 0, + }; + zval* rv; - /* create unpool context */ - if (apc_cache_make_context(cache, &ctxt, APC_CONTEXT_NOSHARE, APC_UNPOOL, APC_COPY_OUT, 0)) { + /* create unpool context */ + if (apc_cache_make_context(cache, &ctxt, APC_CONTEXT_NOSHARE, APC_UNPOOL, APC_COPY_OUT, 0)) { - /* copy to destination */ - rv = apc_cache_fetch_zval(&ctxt, *dst, &entry->val); + /* copy to destination */ + rv = apc_cache_fetch_zval(&ctxt, *dst, &entry->val); - /* release entry */ - apc_cache_release(cache, entry); + /* release entry */ + apc_cache_release(cache, entry); - /* destroy context */ - apc_cache_destroy_context(&ctxt ); + /* destroy context */ + apc_cache_destroy_context(&ctxt); - return (rv != NULL) ? 1 : 0; - } + return (rv != NULL) ? 1 : 0; + } - return 0; + return 0; } /* {{{ apc_cache_store */ -PHP_APCU_API zend_bool apc_cache_store(apc_cache_t* cache, zend_string *strkey, const zval *val, const int32_t ttl, const zend_bool exclusive) { - apc_cache_entry_t *entry; +PHP_APCU_API zend_bool +apc_cache_store(apc_cache_t* cache, zend_string* strkey, const zval* val, const int32_t ttl, const zend_bool exclusive) +{ + apc_cache_entry_t* entry; apc_cache_key_t key; time_t t; - apc_context_t ctxt={0,}; + apc_context_t ctxt = { + 0, + }; zend_bool ret = 0; t = apc_time(); - /* initialize a context suitable for making an insert */ + /* initialize a context suitable for making an insert */ if (apc_cache_make_context(cache, &ctxt, APC_CONTEXT_SHARE, APC_SMALL_POOL, APC_COPY_IN, 0)) { /* initialize the key for insertion */ @@ -544,10 +576,10 @@ PHP_APCU_API zend_bool apc_cache_store(apc_cache_t* cache, zend_string *strkey, /* run cache defense */ if (!apc_cache_defense(cache, &key)) { - + /* initialize the entry for insertion */ if ((entry = apc_cache_make_entry(&ctxt, &key, val, ttl))) { - + /* execute an insertion */ if (apc_cache_insert(cache, &key, entry, &ctxt, t, exclusive)) { ret = 1; @@ -567,31 +599,34 @@ PHP_APCU_API zend_bool apc_cache_store(apc_cache_t* cache, zend_string *strkey, #ifndef ZTS /* {{{ data_unserialize */ -static zval data_unserialize(const char *filename) +static zval +data_unserialize(const char* filename) { zval retval; zend_long len = 0; zend_stat_t sb; char *contents, *tmp; - FILE *fp; - php_unserialize_data_t var_hash = {0,}; + FILE* fp; + php_unserialize_data_t var_hash = { + 0, + }; - if(VCWD_STAT(filename, &sb) == -1) { + if (VCWD_STAT(filename, &sb) == -1) { return EG(uninitialized_zval); } fp = fopen(filename, "rb"); - len = sizeof(char)*sb.st_size; + len = sizeof(char) * sb.st_size; tmp = contents = malloc(len); - if(!contents) { + if (!contents) { fclose(fp); return EG(uninitialized_zval); } - if(fread(contents, 1, len, fp) < 1) { + if (fread(contents, 1, len, fp) < 1) { fclose(fp); free(contents); return EG(uninitialized_zval); @@ -600,9 +635,10 @@ static zval data_unserialize(const char *filename) ZVAL_UNDEF(&retval); PHP_VAR_UNSERIALIZE_INIT(var_hash); - + /* I wish I could use json */ - if(!php_var_unserialize(&retval, (const unsigned char**)&tmp, (const unsigned char*)(contents+len), &var_hash)) { + if (!php_var_unserialize(&retval, (const unsigned char**) &tmp, (const unsigned char*) (contents + len), + &var_hash)) { fclose(fp); free(contents); return EG(uninitialized_zval); @@ -616,30 +652,32 @@ static zval data_unserialize(const char *filename) return retval; } -static int apc_load_data(apc_cache_t* cache, const char *data_file) +static int +apc_load_data(apc_cache_t* cache, const char* data_file) { - char *p; - char key[MAXPATHLEN] = {0,}; + char* p; + char key[MAXPATHLEN] = { + 0, + }; unsigned int key_len; zval data; p = strrchr(data_file, DEFAULT_SLASH); - if(p && p[1]) { - strlcpy(key, p+1, sizeof(key)); + if (p && p[1]) { + strlcpy(key, p + 1, sizeof(key)); p = strrchr(key, '.'); - if(p) { - p[0] = '\0'; + if (p) { + p[0] = '\0'; key_len = strlen(key); data = data_unserialize(data_file); - if(Z_TYPE(data) != IS_UNDEF) { - zend_string *name = zend_string_init(key, key_len, 0); - apc_cache_store( - cache, name, &data, 0, 1); - zend_string_release(name); - zval_dtor(&data); + if (Z_TYPE(data) != IS_UNDEF) { + zend_string* name = zend_string_init(key, key_len, 0); + apc_cache_store(cache, name, &data, 0, 1); + zend_string_release(name); + zval_dtor(&data); } return 1; } @@ -650,282 +688,283 @@ static int apc_load_data(apc_cache_t* cache, const char *data_file) #endif /* {{{ apc_cache_preload shall load the prepared data files in path into the specified cache */ -PHP_APCU_API zend_bool apc_cache_preload(apc_cache_t* cache, const char *path) +PHP_APCU_API zend_bool +apc_cache_preload(apc_cache_t* cache, const char* path) { -#ifndef ZTS - zend_bool result = 0; - char file[MAXPATHLEN]={0,}; - int ndir, i; - char *p = NULL; - struct dirent **namelist = NULL; - - if ((ndir = php_scandir(path, &namelist, 0, php_alphasort)) > 0) { - for (i = 0; i < ndir; i++) { - /* check for extension */ - if (!(p = strrchr(namelist[i]->d_name, '.')) - || (p && strcmp(p, ".data"))) { - free(namelist[i]); - continue; - } - - snprintf(file, MAXPATHLEN, "%s%c%s", - path, DEFAULT_SLASH, namelist[i]->d_name); - - if(apc_load_data(cache, file)) { - result = 1; - } - free(namelist[i]); - } - free(namelist); - } - return result; -#else - apc_error("Cannot load data from apc.preload_path=%s in thread-safe mode", path); - return 0; -#endif +#ifndef ZTS + zend_bool result = 0; + char file[MAXPATHLEN] = { + 0, + }; + int ndir, i; + char* p = NULL; + struct dirent** namelist = NULL; + + if ((ndir = php_scandir(path, &namelist, 0, php_alphasort)) > 0) { + for (i = 0; i < ndir; i++) { + /* check for extension */ + if (!(p = strrchr(namelist[i]->d_name, '.')) || (p && strcmp(p, ".data"))) { + free(namelist[i]); + continue; + } + + snprintf(file, MAXPATHLEN, "%s%c%s", path, DEFAULT_SLASH, namelist[i]->d_name); + + if (apc_load_data(cache, file)) { + result = 1; + } + free(namelist[i]); + } + free(namelist); + } + return result; +#else + apc_error("Cannot load data from apc.preload_path=%s in thread-safe mode", path); + return 0; +#endif } /* }}} */ /* {{{ apc_cache_release */ -PHP_APCU_API void apc_cache_release(apc_cache_t* cache, apc_cache_entry_t* entry) +PHP_APCU_API void +apc_cache_release(apc_cache_t* cache, apc_cache_entry_t* entry) { ATOMIC_DEC(cache, entry->ref_count); } /* }}} */ /* {{{ apc_cache_destroy */ -PHP_APCU_API void apc_cache_destroy(apc_cache_t* cache) +PHP_APCU_API void +apc_cache_destroy(apc_cache_t* cache) { - if (!cache) { - return; - } + if (!cache) { + return; + } - /* destroy lock */ - DESTROY_LOCK(&cache->header->lock); + /* destroy lock */ + DESTROY_LOCK(&cache->header->lock); - /* XXX this is definitely a leak, but freeing this causes all the apache - children to freeze. It might be because the segment is shared between - several processes. To figure out is how to free this safely. */ + /* XXX this is definitely a leak, but freeing this causes all the apache + children to freeze. It might be because the segment is shared between + several processes. To figure out is how to free this safely. */ /*apc_sma_free(cache->shmaddr);*/ apc_efree(cache); } /* }}} */ /* {{{ apc_cache_real_expunge */ -PHP_APCU_API void apc_cache_real_expunge(apc_cache_t* cache) { - /* increment counter */ - cache->header->nexpunges++; - - /* expunge */ +PHP_APCU_API void +apc_cache_real_expunge(apc_cache_t* cache) +{ + /* increment counter */ + cache->header->nexpunges++; + + /* expunge */ { - zend_ulong i; - - for (i = 0; i < cache->nslots; i++) { - apc_cache_slot_t* p = cache->slots[i]; - while (p) { - apc_cache_remove_slot(cache, &p); - } - cache->slots[i] = NULL; - } - } - - /* set new time so counters make sense */ - cache->header->stime = apc_time(); - - /* reset counters */ - cache->header->ninserts = 0; - cache->header->nentries = 0; - cache->header->nhits = 0; - cache->header->nmisses = 0; - - /* resets lastkey */ - memset(&cache->header->lastkey, 0, sizeof(apc_cache_key_t)); + zend_ulong i; + + for (i = 0; i < cache->nslots; i++) { + apc_cache_slot_t* p = cache->slots[i]; + while (p) { + apc_cache_remove_slot(cache, &p); + } + cache->slots[i] = NULL; + } + } + + /* set new time so counters make sense */ + cache->header->stime = apc_time(); + + /* reset counters */ + cache->header->ninserts = 0; + cache->header->nentries = 0; + cache->header->nhits = 0; + cache->header->nmisses = 0; + + /* resets lastkey */ + memset(&cache->header->lastkey, 0, sizeof(apc_cache_key_t)); } /* }}} */ /* {{{ apc_cache_clear */ -PHP_APCU_API void apc_cache_clear(apc_cache_t* cache) +PHP_APCU_API void +apc_cache_clear(apc_cache_t* cache) { - /* check there is a cache and it is not busy */ - if(!cache || apc_cache_busy(cache)) { - return; - } - - /* lock header */ - APC_LOCK(cache->header); + /* check there is a cache and it is not busy */ + if (!cache || apc_cache_busy(cache)) { + return; + } - /* set busy */ - cache->header->state |= APC_CACHE_ST_BUSY; + /* lock header */ + APC_LOCK(cache->header); - /* expunge cache */ - apc_cache_real_expunge(cache); + /* set busy */ + cache->header->state |= APC_CACHE_ST_BUSY; - /* set info */ - cache->header->stime = apc_time(); - cache->header->nexpunges = 0; + /* expunge cache */ + apc_cache_real_expunge(cache); + + /* set info */ + cache->header->stime = apc_time(); + cache->header->nexpunges = 0; - /* unset busy */ - cache->header->state &= ~APC_CACHE_ST_BUSY; + /* unset busy */ + cache->header->state &= ~APC_CACHE_ST_BUSY; - /* unlock header */ - APC_UNLOCK(cache->header); + /* unlock header */ + APC_UNLOCK(cache->header); } /* }}} */ /* {{{ apc_cache_default_expunge */ -PHP_APCU_API void apc_cache_default_expunge(apc_cache_t* cache, size_t size) +PHP_APCU_API void +apc_cache_default_expunge(apc_cache_t* cache, size_t size) { time_t t; - size_t suitable = 0L; + size_t suitable = 0L; size_t available = 0L; t = apc_time(); - /* check there is a cache, and it is not busy */ - if(!cache || apc_cache_busy(cache)) { - return; - } - - /* get the lock for header */ - APC_LOCK(cache->header); - - /* update state in header */ - cache->header->state |= APC_CACHE_ST_BUSY; - - /* make suitable selection */ - suitable = (cache->smart > 0L) ? (size_t) (cache->smart * size) : (size_t) (cache->sma->size/2); - - /* gc */ - apc_cache_gc(cache); - - /* get available */ - available = cache->sma->get_avail_mem(); - - /* perform expunge processing */ - if(!cache->ttl) { - - /* check it is necessary to expunge */ - if (available < suitable) { - apc_cache_real_expunge(cache); - } - } else { - apc_cache_slot_t **slot; - - /* check that expunge is necessary */ - if (available < suitable) { - zend_ulong i; - - /* look for junk */ - for (i = 0; i < cache->nslots; i++) { - slot = &cache->slots[i]; - while (*slot) { - /* - * Entry TTL has precedence over cache TTL - */ - if((*slot)->value->ttl) { - if((time_t) ((*slot)->ctime + (*slot)->value->ttl) < t) { - apc_cache_remove_slot(cache, slot); - continue; - } - } else if(cache->ttl) { - if((time_t) ((*slot)->ctime + cache->ttl) < t) { - apc_cache_remove_slot(cache, slot); - continue; - } - } - - /* grab next slot */ - slot = &(*slot)->next; - } - } - - /* if the cache now has space, then reset last key */ - if (cache->sma->get_avail_size(size)) { - /* wipe lastkey */ - memset(&cache->header->lastkey, 0, sizeof(apc_cache_key_t)); - } else { - /* with not enough space left in cache, we are forced to expunge */ - apc_cache_real_expunge(cache); - } - } - } - - /* we are done */ - cache->header->state &= ~APC_CACHE_ST_BUSY; - - /* unlock header */ - APC_UNLOCK(cache->header); + /* check there is a cache, and it is not busy */ + if (!cache || apc_cache_busy(cache)) { + return; + } + + /* get the lock for header */ + APC_LOCK(cache->header); + + /* update state in header */ + cache->header->state |= APC_CACHE_ST_BUSY; + + /* make suitable selection */ + suitable = (cache->smart > 0L) ? (size_t)(cache->smart * size) : (size_t)(cache->sma->size / 2); + + /* gc */ + apc_cache_gc(cache); + + /* get available */ + available = cache->sma->get_avail_mem(); + + /* perform expunge processing */ + if (!cache->ttl) { + + /* check it is necessary to expunge */ + if (available < suitable) { + apc_cache_real_expunge(cache); + } + } else { + apc_cache_slot_t** slot; + + /* check that expunge is necessary */ + if (available < suitable) { + zend_ulong i; + + /* look for junk */ + for (i = 0; i < cache->nslots; i++) { + slot = &cache->slots[i]; + while (*slot) { + /* + * Entry TTL has precedence over cache TTL + */ + if ((*slot)->value->ttl) { + if ((time_t)((*slot)->ctime + (*slot)->value->ttl) < t) { + apc_cache_remove_slot(cache, slot); + continue; + } + } else if (cache->ttl) { + if ((time_t)((*slot)->ctime + cache->ttl) < t) { + apc_cache_remove_slot(cache, slot); + continue; + } + } + + /* grab next slot */ + slot = &(*slot)->next; + } + } + + /* if the cache now has space, then reset last key */ + if (cache->sma->get_avail_size(size)) { + /* wipe lastkey */ + memset(&cache->header->lastkey, 0, sizeof(apc_cache_key_t)); + } else { + /* with not enough space left in cache, we are forced to expunge */ + apc_cache_real_expunge(cache); + } + } + } + + /* we are done */ + cache->header->state &= ~APC_CACHE_ST_BUSY; + + /* unlock header */ + APC_UNLOCK(cache->header); } /* }}} */ /* {{{ apc_cache_make_context */ -PHP_APCU_API zend_bool apc_cache_make_context(apc_cache_t* cache, - apc_context_t* context, - apc_context_type context_type, - apc_pool_type pool_type, - apc_copy_type copy_type, - uint force_update) { - switch (context_type) { - case APC_CONTEXT_SHARE: { - return apc_cache_make_context_ex( - context, - cache->serializer, - (apc_malloc_t) cache->sma->smalloc, - cache->sma->sfree, - cache->sma->protect, - cache->sma->unprotect, - pool_type, copy_type, force_update - ); - } break; - - case APC_CONTEXT_NOSHARE: { - return apc_cache_make_context_ex( - context, - cache->serializer, - apc_php_malloc, apc_php_free, NULL, NULL, - pool_type, copy_type, force_update - ); - } break; - - case APC_CONTEXT_NONE: - /* never used, just to make gcc warning free */ - break; - } - - return 0; +PHP_APCU_API zend_bool +apc_cache_make_context(apc_cache_t* cache, + apc_context_t* context, + apc_context_type context_type, + apc_pool_type pool_type, + apc_copy_type copy_type, + uint force_update) +{ + switch (context_type) { + case APC_CONTEXT_SHARE: { + return apc_cache_make_context_ex(context, cache->serializer, (apc_malloc_t) cache->sma->smalloc, + cache->sma->sfree, cache->sma->protect, cache->sma->unprotect, pool_type, + copy_type, force_update); + } break; + + case APC_CONTEXT_NOSHARE: { + return apc_cache_make_context_ex(context, cache->serializer, apc_php_malloc, apc_php_free, NULL, NULL, + pool_type, copy_type, force_update); + } break; + + case APC_CONTEXT_NONE: + /* never used, just to make gcc warning free */ + break; + } + + return 0; } /* }}} */ /* {{{ apc_cache_make_context_ex */ -PHP_APCU_API zend_bool apc_cache_make_context_ex(apc_context_t* context, - apc_serializer_t* serializer, - apc_malloc_t _malloc, - apc_free_t _free, - apc_protect_t _protect, - apc_unprotect_t _unprotect, - apc_pool_type pool_type, - apc_copy_type copy_type, - uint force_update) { - /* attempt to create the pool */ - context->pool = apc_pool_create( - pool_type, _malloc, _free, _protect, _unprotect - ); - - if (!context->pool) { - apc_warning("Unable to allocate memory for pool."); - return 0; - } - - /* set context information */ - context->serializer = serializer; - context->copy = copy_type; - context->force_update = force_update; - - /* set this to avoid memory errors */ - memset(&context->copied, 0, sizeof(HashTable)); - - return 1; +PHP_APCU_API zend_bool +apc_cache_make_context_ex(apc_context_t* context, + apc_serializer_t* serializer, + apc_malloc_t _malloc, + apc_free_t _free, + apc_protect_t _protect, + apc_unprotect_t _unprotect, + apc_pool_type pool_type, + apc_copy_type copy_type, + uint force_update) +{ + /* attempt to create the pool */ + context->pool = apc_pool_create(pool_type, _malloc, _free, _protect, _unprotect); + + if (!context->pool) { + apc_warning("Unable to allocate memory for pool."); + return 0; + } + + /* set context information */ + context->serializer = serializer; + context->copy = copy_type; + context->force_update = force_update; + + /* set this to avoid memory errors */ + memset(&context->copied, 0, sizeof(HashTable)); + + return 1; } /* }}} */ /* {{{ apc_context_destroy */ -PHP_APCU_API zend_bool apc_cache_destroy_context(apc_context_t* context) { +PHP_APCU_API zend_bool +apc_cache_destroy_context(apc_context_t* context) +{ if (!context->pool) { return 0; } @@ -936,251 +975,252 @@ PHP_APCU_API zend_bool apc_cache_destroy_context(apc_context_t* context) { } /* }}} */ /* {{{ apc_cache_insert */ -PHP_APCU_API zend_bool apc_cache_insert(apc_cache_t* cache, - apc_cache_key_t *key, - apc_cache_entry_t* value, - apc_context_t* ctxt, - time_t t, - zend_bool exclusive) +PHP_APCU_API zend_bool +apc_cache_insert(apc_cache_t* cache, + apc_cache_key_t* key, + apc_cache_entry_t* value, + apc_context_t* ctxt, + time_t t, + zend_bool exclusive) { - zend_bool result = 0; + zend_bool result = 0; - php_apc_try(APC_LOCK(cache->header), { - result = apc_cache_insert_internal( - cache, key, value, ctxt, t, exclusive); - }, APC_UNLOCK(cache->header)); + php_apc_try(APC_LOCK(cache->header), { result = apc_cache_insert_internal(cache, key, value, ctxt, t, exclusive); }, + APC_UNLOCK(cache->header)); - return result; + return result; } /* }}} */ /* {{{ apc_cache_find */ -PHP_APCU_API apc_cache_entry_t* apc_cache_find(apc_cache_t* cache, zend_string *key, time_t t) +PHP_APCU_API apc_cache_entry_t* +apc_cache_find(apc_cache_t* cache, zend_string* key, time_t t) { - apc_cache_entry_t *entry = NULL; + apc_cache_entry_t* entry = NULL; - /* check we are able to deal with the request */ - if(!cache || apc_cache_busy(cache)) { + /* check we are able to deal with the request */ + if (!cache || apc_cache_busy(cache)) { return entry; } - entry = apc_cache_find_internal(cache, key, t, 1); + entry = apc_cache_find_internal(cache, key, t, 1); - return entry; + return entry; } /* }}} */ /* {{{ apc_cache_fetch */ -PHP_APCU_API zend_bool apc_cache_fetch(apc_cache_t* cache, zend_string *key, time_t t, zval **dst) +PHP_APCU_API zend_bool +apc_cache_fetch(apc_cache_t* cache, zend_string* key, time_t t, zval** dst) { - apc_cache_entry_t *entry = NULL; - zend_bool ret = 0; + apc_cache_entry_t* entry = NULL; + zend_bool ret = 0; - /* check we are able to deal with the request */ - if(!cache || apc_cache_busy(cache)) { + /* check we are able to deal with the request */ + if (!cache || apc_cache_busy(cache)) { return 0; } - entry = apc_cache_find_internal(cache, key, t, 1); + entry = apc_cache_find_internal(cache, key, t, 1); + + if (entry) { + ret = apc_cache_fetch_internal(cache, key, entry, t, dst); + } - if (entry) { - ret = apc_cache_fetch_internal(cache, key, entry, t, dst); - } - - return ret; + return ret; } /* }}} */ /* {{{ apc_cache_exists */ -PHP_APCU_API apc_cache_entry_t* apc_cache_exists(apc_cache_t* cache, zend_string *key, time_t t) +PHP_APCU_API apc_cache_entry_t* +apc_cache_exists(apc_cache_t* cache, zend_string* key, time_t t) { - if(apc_cache_busy(cache)) - { - /* cache cleanup in progress */ + if (apc_cache_busy(cache)) { + /* cache cleanup in progress */ return NULL; } - /* we only declare volatiles we need */ - { - apc_cache_slot_t** slot; - - volatile apc_cache_entry_t* value = NULL; - zend_ulong h, s; + /* we only declare volatiles we need */ + { + apc_cache_slot_t** slot; + + volatile apc_cache_entry_t* value = NULL; + zend_ulong h, s; /* get hash and slot */ - apc_cache_hash_slot(cache, key, &h, &s); + apc_cache_hash_slot(cache, key, &h, &s); /* read lock header */ - APC_RLOCK(cache->header); + APC_RLOCK(cache->header); - /* find head */ - slot = &cache->slots[s]; + /* find head */ + slot = &cache->slots[s]; - while (*slot) { - /* check for match by hash and identifier */ - if ((h == ZSTR_HASH((*slot)->key.str)) && - memcmp(ZSTR_VAL((*slot)->key.str), ZSTR_VAL(key), ZSTR_LEN(key)) == SUCCESS) { + while (*slot) { + /* check for match by hash and identifier */ + if ((h == ZSTR_HASH((*slot)->key.str)) && + memcmp(ZSTR_VAL((*slot)->key.str), ZSTR_VAL(key), ZSTR_LEN(key)) == SUCCESS) { - /* Check to make sure this entry isn't expired by a hard TTL */ - if((*slot)->value->ttl && (time_t) ((*slot)->ctime + (*slot)->value->ttl) < t) { + /* Check to make sure this entry isn't expired by a hard TTL */ + if ((*slot)->value->ttl && (time_t)((*slot)->ctime + (*slot)->value->ttl) < t) { /* marked as a miss */ ATOMIC_INC(cache, cache->header->nmisses); - /* unlock header */ - APC_RUNLOCK(cache->header); + /* unlock header */ + APC_RUNLOCK(cache->header); - return NULL; - } + return NULL; + } + + /* Return the cache entry ptr */ + value = (*slot)->value; - /* Return the cache entry ptr */ - value = (*slot)->value; - - /* unlock header */ - APC_RUNLOCK(cache->header); - - return (apc_cache_entry_t*)value; - } + /* unlock header */ + APC_RUNLOCK(cache->header); + + return (apc_cache_entry_t*) value; + } - slot = &(*slot)->next; - } + slot = &(*slot)->next; + } - /* unlock header */ - APC_RUNLOCK(cache->header); - } + /* unlock header */ + APC_RUNLOCK(cache->header); + } return NULL; } /* }}} */ /* {{{ apc_cache_update */ -PHP_APCU_API zend_bool apc_cache_update(apc_cache_t* cache, zend_string *key, apc_cache_updater_t updater, void* data) +PHP_APCU_API zend_bool +apc_cache_update(apc_cache_t* cache, zend_string* key, apc_cache_updater_t updater, void* data) { apc_cache_slot_t** slot; apc_cache_entry_t tmp_entry; - + zend_bool retval = 0; zend_ulong h, s; - if(apc_cache_busy(cache)) - { - /* cannot service request right now */ + if (apc_cache_busy(cache)) { + /* cannot service request right now */ return 0; } /* calculate hash */ apc_cache_hash_slot(cache, key, &h, &s); - - php_apc_try(APC_LOCK(cache->header), { - - /* find head */ - slot = &cache->slots[s]; - - while (*slot) { - /* check for a match by hash and identifier */ - if ((h == ZSTR_HASH((*slot)->key.str)) && - memcmp(ZSTR_VAL((*slot)->key.str), ZSTR_VAL(key), ZSTR_LEN(key)) == SUCCESS) { - /* attempt to perform update */ - switch(Z_TYPE((*slot)->value->val)) { - case IS_ARRAY: - case IS_OBJECT: - { - if(cache->serializer) { - retval = 0; - break; - } - } - - /* break intentionally omitted */ - - default: - { - /* executing update */ - retval = updater(cache, (*slot)->value, data); - /* set modified time */ - (*slot)->key.mtime = apc_time(); - } - break; - } - - php_apc_try_end({ - APC_UNLOCK(cache->header); - return retval; - }); - } - - /* set next slot */ - slot = &(*slot)->next; - } - }, APC_UNLOCK(cache->header)); - - /* failed to find matching entry, create it */ - ZVAL_LONG(&tmp_entry.val, 0); - updater(cache, &tmp_entry, data); - - if(apc_cache_store(cache, key, &tmp_entry.val, 0, 0)) { - return 1; - } + + php_apc_try(APC_LOCK(cache->header), + { + + /* find head */ + slot = &cache->slots[s]; + + while (*slot) { + /* check for a match by hash and identifier */ + if ((h == ZSTR_HASH((*slot)->key.str)) && + memcmp(ZSTR_VAL((*slot)->key.str), ZSTR_VAL(key), ZSTR_LEN(key)) == SUCCESS) { + /* attempt to perform update */ + switch (Z_TYPE((*slot)->value->val)) { + case IS_ARRAY: + case IS_OBJECT: { + if (cache->serializer) { + retval = 0; + break; + } + } + + /* break intentionally omitted */ + + default: { + /* executing update */ + retval = updater(cache, (*slot)->value, data); + /* set modified time */ + (*slot)->key.mtime = apc_time(); + } break; + } + + php_apc_try_end({ + APC_UNLOCK(cache->header); + return retval; + }); + } + + /* set next slot */ + slot = &(*slot)->next; + } + }, + APC_UNLOCK(cache->header)); + + /* failed to find matching entry, create it */ + ZVAL_LONG(&tmp_entry.val, 0); + updater(cache, &tmp_entry, data); + + if (apc_cache_store(cache, key, &tmp_entry.val, 0, 0)) { + return 1; + } return 0; } /* }}} */ /* {{{ apc_cache_delete */ -PHP_APCU_API zend_bool apc_cache_delete(apc_cache_t* cache, zend_string *key) +PHP_APCU_API zend_bool +apc_cache_delete(apc_cache_t* cache, zend_string* key) { apc_cache_slot_t** slot; - + zend_ulong h, s; - if (!cache) { - return 1; - } + if (!cache) { + return 1; + } /* calculate hash and slot */ apc_cache_hash_slot(cache, key, &h, &s); - /* lock cache */ - APC_LOCK(cache->header); - - /* find head */ + /* lock cache */ + APC_LOCK(cache->header); + + /* find head */ slot = &cache->slots[s]; while (*slot) { - /* check for a match by hash and identifier */ - if ((h == ZSTR_HASH((*slot)->key.str)) && + /* check for a match by hash and identifier */ + if ((h == ZSTR_HASH((*slot)->key.str)) && memcmp(ZSTR_VAL((*slot)->key.str), ZSTR_VAL(key), ZSTR_LEN(key)) == SUCCESS) { - /* executing removal */ - apc_cache_remove_slot( - cache, slot); - goto deleted; + /* executing removal */ + apc_cache_remove_slot(cache, slot); + goto deleted; } - - /* continue locking */ - slot = &(*slot)->next; + + /* continue locking */ + slot = &(*slot)->next; } - - /* unlock header */ - APC_UNLOCK(cache->header); - - return 0; + + /* unlock header */ + APC_UNLOCK(cache->header); + + return 0; deleted: - /* unlock deleted */ - APC_UNLOCK(cache->header); + /* unlock deleted */ + APC_UNLOCK(cache->header); - return 1; + return 1; } /* }}} */ /* {{{ apc_cache_make_key */ -PHP_APCU_API zend_bool apc_cache_make_key(apc_cache_key_t* key, zend_string *str) +PHP_APCU_API zend_bool +apc_cache_make_key(apc_cache_key_t* key, zend_string* str) { assert(key != NULL); if (!str) { - return 0; + return 0; } - - key->str = str; + + key->str = str; key->mtime = apc_time(); return 1; @@ -1188,38 +1228,38 @@ PHP_APCU_API zend_bool apc_cache_make_key(apc_cache_key_t* key, zend_string *str /* }}} */ /* {{{ my_serialize_object */ -static zval* my_serialize_object(zval* dst, const zval* src, apc_context_t* ctxt) +static zval* +my_serialize_object(zval* dst, const zval* src, apc_context_t* ctxt) { - unsigned char *buf = NULL; - size_t buf_len = 0; - - apc_pool* pool = ctxt->pool; + unsigned char* buf = NULL; + size_t buf_len = 0; + + apc_pool* pool = ctxt->pool; apc_serialize_t serialize = APC_SERIALIZER_NAME(php); - void *config = NULL; - zend_string *serial = NULL; + void* config = NULL; + zend_string* serial = NULL; - if(ctxt->serializer) { + if (ctxt->serializer) { serialize = ctxt->serializer->serialize; - config = - (ctxt->serializer->config != NULL) ? - ctxt->serializer->config : ctxt; + config = (ctxt->serializer->config != NULL) ? ctxt->serializer->config : ctxt; } - ZVAL_NULL(dst); + ZVAL_NULL(dst); - if(serialize((unsigned char**)&buf, &buf_len, src, config)) { - if (!(serial = apc_pstrnew(buf, buf_len, pool))) { - efree(buf); + if (serialize((unsigned char**) &buf, &buf_len, src, config)) { + if (!(serial = apc_pstrnew(buf, buf_len, pool))) { + efree(buf); - return dst; - } + return dst; + } - ZVAL_STR(dst, serial); - /* Give this the type of an object/array, and the same type flags as a string. */ - /* The only necessary one is probably IS_TYPE_REFCOUNTED - (We check Z_REFCOUNTED_P when de-duplicating serialized values. */ - /* Probably safe - When copying strings into shared memory, the code gives it type IS_STRING_EX, */ - Z_TYPE_INFO_P(dst) = Z_TYPE_P(src) | ((IS_TYPE_REFCOUNTED | IS_TYPE_COPYABLE) << Z_TYPE_FLAGS_SHIFT); - efree(buf); + ZVAL_STR(dst, serial); + /* Give this the type of an object/array, and the same type flags as a string. */ + /* The only necessary one is probably IS_TYPE_REFCOUNTED - (We check Z_REFCOUNTED_P when de-duplicating + * serialized values. */ + /* Probably safe - When copying strings into shared memory, the code gives it type IS_STRING_EX, */ + Z_TYPE_INFO_P(dst) = Z_TYPE_P(src) | ((IS_TYPE_REFCOUNTED | IS_TYPE_COPYABLE) << Z_TYPE_FLAGS_SHIFT); + efree(buf); } return dst; @@ -1227,17 +1267,18 @@ static zval* my_serialize_object(zval* dst, const zval* src, apc_context_t* ctxt /* }}} */ /* {{{ my_unserialize_object */ -static zval* my_unserialize_object(zval* dst, const zval* src, apc_context_t* ctxt) +static zval* +my_unserialize_object(zval* dst, const zval* src, apc_context_t* ctxt) { apc_unserialize_t unserialize = APC_UNSERIALIZER_NAME(php); - void *config = NULL; + void* config = NULL; - if(ctxt->serializer) { + if (ctxt->serializer) { unserialize = ctxt->serializer->unserialize; - config = (ctxt->serializer->config != NULL) ? ctxt->serializer->config : ctxt; + config = (ctxt->serializer->config != NULL) ? ctxt->serializer->config : ctxt; } - if(unserialize(dst, (unsigned char *)Z_STRVAL_P(src), Z_STRLEN_P(src), config)) { + if (unserialize(dst, (unsigned char*) Z_STRVAL_P(src), Z_STRLEN_P(src), config)) { return dst; } else { zval_dtor(dst); @@ -1247,233 +1288,251 @@ static zval* my_unserialize_object(zval* dst, const zval* src, apc_context_t* ct } /* }}} */ -static const uint32_t uninitialized_bucket[-HT_MIN_MASK] = {HT_INVALID_IDX, HT_INVALID_IDX}; - -static zend_always_inline int apc_array_dup_element(apc_context_t *ctxt, HashTable *source, HashTable *target, uint32_t idx, Bucket *p, Bucket *q, int packed, int static_keys, int with_holes) +static const uint32_t uninitialized_bucket[-HT_MIN_MASK] = { HT_INVALID_IDX, HT_INVALID_IDX }; + +static zend_always_inline int +apc_array_dup_element(apc_context_t* ctxt, + HashTable* source, + HashTable* target, + uint32_t idx, + Bucket* p, + Bucket* q, + int packed, + int static_keys, + int with_holes) { - zval *data = &p->val; - - if (with_holes) { - if (!packed && Z_TYPE_INFO_P(data) == IS_INDIRECT) { - data = Z_INDIRECT_P(data); - } - if (UNEXPECTED(Z_TYPE_INFO_P(data) == IS_UNDEF)) { - return 0; - } - } else if (!packed) { - /* INDIRECT element may point to UNDEF-ined slots */ - if (Z_TYPE_INFO_P(data) == IS_INDIRECT) { - data = Z_INDIRECT_P(data); - if (UNEXPECTED(Z_TYPE_INFO_P(data) == IS_UNDEF)) { - return 0; - } - } - } - - do { - if (Z_OPT_REFCOUNTED_P(data)) { - if (Z_ISREF_P(data) && Z_REFCOUNT_P(data) == 1 && - (Z_TYPE_P(Z_REFVAL_P(data)) != IS_ARRAY || - Z_ARRVAL_P(Z_REFVAL_P(data)) != source)) { - data = Z_REFVAL_P(data); - if (!Z_OPT_REFCOUNTED_P(data)) { - break; - } - } - } - } while (0); - - if (my_copy_zval(&q->val, data, ctxt) == NULL) + zval* data = &p->val; + + if (with_holes) { + if (!packed && Z_TYPE_INFO_P(data) == IS_INDIRECT) { + data = Z_INDIRECT_P(data); + } + if (UNEXPECTED(Z_TYPE_INFO_P(data) == IS_UNDEF)) { + return 0; + } + } else if (!packed) { + /* INDIRECT element may point to UNDEF-ined slots */ + if (Z_TYPE_INFO_P(data) == IS_INDIRECT) { + data = Z_INDIRECT_P(data); + if (UNEXPECTED(Z_TYPE_INFO_P(data) == IS_UNDEF)) { + return 0; + } + } + } + + do { + if (Z_OPT_REFCOUNTED_P(data)) { + if (Z_ISREF_P(data) && Z_REFCOUNT_P(data) == 1 && + (Z_TYPE_P(Z_REFVAL_P(data)) != IS_ARRAY || Z_ARRVAL_P(Z_REFVAL_P(data)) != source)) { + data = Z_REFVAL_P(data); + if (!Z_OPT_REFCOUNTED_P(data)) { + break; + } + } + } + } while (0); + + if (my_copy_zval(&q->val, data, ctxt) == NULL) return 0; - q->h = p->h; - if (packed) { - q->key = NULL; - } else { - uint32_t nIndex; - - q->key = p->key; - if (!static_keys && q->key) { - if (ctxt->copy == APC_COPY_IN) { - q->key = apc_pstrcpy(q->key, ctxt->pool); - } else q->key = p->key; - } - - nIndex = q->h | target->nTableMask; - Z_NEXT(q->val) = HT_HASH(target, nIndex); - HT_HASH(target, nIndex) = HT_IDX_TO_HASH(idx); - } - return 1; + q->h = p->h; + if (packed) { + q->key = NULL; + } else { + uint32_t nIndex; + + q->key = p->key; + if (!static_keys && q->key) { + if (ctxt->copy == APC_COPY_IN) { + q->key = apc_pstrcpy(q->key, ctxt->pool); + } else + q->key = p->key; + } + + nIndex = q->h | target->nTableMask; + Z_NEXT(q->val) = HT_HASH(target, nIndex); + HT_HASH(target, nIndex) = HT_IDX_TO_HASH(idx); + } + return 1; } -static zend_always_inline void apc_array_dup_packed_elements(apc_context_t *ctxt, HashTable *source, HashTable *target, int with_holes) +static zend_always_inline void +apc_array_dup_packed_elements(apc_context_t* ctxt, HashTable* source, HashTable* target, int with_holes) { - Bucket *p = source->arData; - Bucket *q = target->arData; - Bucket *end = p + source->nNumUsed; - - do { - if (!apc_array_dup_element(ctxt, source, target, 0, p, q, 1, 1, with_holes)) { - if (with_holes) { - ZVAL_UNDEF(&q->val); - } - } - p++; q++; - } while (p != end); + Bucket* p = source->arData; + Bucket* q = target->arData; + Bucket* end = p + source->nNumUsed; + + do { + if (!apc_array_dup_element(ctxt, source, target, 0, p, q, 1, 1, with_holes)) { + if (with_holes) { + ZVAL_UNDEF(&q->val); + } + } + p++; + q++; + } while (p != end); } -static zend_always_inline uint32_t apc_array_dup_elements(apc_context_t *ctxt, HashTable *source, HashTable *target, int static_keys, int with_holes) +static zend_always_inline uint32_t +apc_array_dup_elements(apc_context_t* ctxt, HashTable* source, HashTable* target, int static_keys, int with_holes) { uint32_t idx = 0; - Bucket *p = source->arData; - Bucket *q = target->arData; - Bucket *end = p + source->nNumUsed; - - do { - if (!apc_array_dup_element(ctxt, source, target, idx, p, q, 0, static_keys, with_holes)) { - uint32_t target_idx = idx; - - idx++; p++; - while (p != end) { - if (apc_array_dup_element(ctxt, source, target, target_idx, p, q, 0, static_keys, with_holes)) { - if (source->nInternalPointer == idx) { - target->nInternalPointer = target_idx; - } - target_idx++; q++; - } - idx++; p++; - } - return target_idx; - } - idx++; p++; q++; - } while (p != end); - return idx; + Bucket* p = source->arData; + Bucket* q = target->arData; + Bucket* end = p + source->nNumUsed; + + do { + if (!apc_array_dup_element(ctxt, source, target, idx, p, q, 0, static_keys, with_holes)) { + uint32_t target_idx = idx; + + idx++; + p++; + while (p != end) { + if (apc_array_dup_element(ctxt, source, target, target_idx, p, q, 0, static_keys, with_holes)) { + if (source->nInternalPointer == idx) { + target->nInternalPointer = target_idx; + } + target_idx++; + q++; + } + idx++; + p++; + } + return target_idx; + } + idx++; + p++; + q++; + } while (p != end); + return idx; } -static APC_HOTSPOT HashTable* my_copy_hashtable(HashTable *source, apc_context_t *ctxt) { - uint32_t idx; - HashTable *target; - apc_pool *pool = ctxt->pool; +static APC_HOTSPOT HashTable* +my_copy_hashtable(HashTable* source, apc_context_t* ctxt) +{ + uint32_t idx; + HashTable* target; + apc_pool* pool = ctxt->pool; - if (ctxt->copy == APC_COPY_IN) { - target = (HashTable*) pool->palloc(pool, sizeof(HashTable)); - } else + if (ctxt->copy == APC_COPY_IN) { + target = (HashTable*) pool->palloc(pool, sizeof(HashTable)); + } else ALLOC_HASHTABLE(target); if (target == NULL) goto bad; - GC_REFCOUNT(target) = 1; - GC_TYPE_INFO(target) = IS_ARRAY; + GC_REFCOUNT(target) = 1; + GC_TYPE_INFO(target) = IS_ARRAY; zend_hash_index_update_ptr(&ctxt->copied, (uintptr_t) source, target); - target->nTableSize = source->nTableSize; - target->pDestructor = source->pDestructor; - - if (source->nNumUsed == 0) { - target->u.flags = (source->u.flags & ~(HASH_FLAG_INITIALIZED|HASH_FLAG_PACKED|HASH_FLAG_PERSISTENT)) | HASH_FLAG_APPLY_PROTECTION | HASH_FLAG_STATIC_KEYS; - target->nTableMask = HT_MIN_MASK; - target->nNumUsed = 0; - target->nNumOfElements = 0; - target->nNextFreeElement = 0; - target->nInternalPointer = HT_INVALID_IDX; - HT_SET_DATA_ADDR(target, &uninitialized_bucket); - } else if (GC_FLAGS(source) & IS_ARRAY_IMMUTABLE) { - target->u.flags = (source->u.flags & ~HASH_FLAG_PERSISTENT) | HASH_FLAG_APPLY_PROTECTION; - target->nTableMask = source->nTableMask; - target->nNumUsed = source->nNumUsed; - target->nNumOfElements = source->nNumOfElements; - target->nNextFreeElement = source->nNextFreeElement; - if (ctxt->copy == APC_COPY_IN) { - HT_SET_DATA_ADDR(target, pool->palloc(pool, HT_SIZE(target))); - } else + target->nTableSize = source->nTableSize; + target->pDestructor = source->pDestructor; + + if (source->nNumUsed == 0) { + target->u.flags = (source->u.flags & ~(HASH_FLAG_INITIALIZED | HASH_FLAG_PACKED | HASH_FLAG_PERSISTENT)) | + HASH_FLAG_APPLY_PROTECTION | HASH_FLAG_STATIC_KEYS; + target->nTableMask = HT_MIN_MASK; + target->nNumUsed = 0; + target->nNumOfElements = 0; + target->nNextFreeElement = 0; + target->nInternalPointer = HT_INVALID_IDX; + HT_SET_DATA_ADDR(target, &uninitialized_bucket); + } else if (GC_FLAGS(source) & IS_ARRAY_IMMUTABLE) { + target->u.flags = (source->u.flags & ~HASH_FLAG_PERSISTENT) | HASH_FLAG_APPLY_PROTECTION; + target->nTableMask = source->nTableMask; + target->nNumUsed = source->nNumUsed; + target->nNumOfElements = source->nNumOfElements; + target->nNextFreeElement = source->nNextFreeElement; + if (ctxt->copy == APC_COPY_IN) { + HT_SET_DATA_ADDR(target, pool->palloc(pool, HT_SIZE(target))); + } else HT_SET_DATA_ADDR(target, emalloc(HT_SIZE(target))); if (HT_GET_DATA_ADDR(target) == NULL) goto bad; - target->nInternalPointer = source->nInternalPointer; - memcpy(HT_GET_DATA_ADDR(target), HT_GET_DATA_ADDR(source), HT_USED_SIZE(source)); - if (target->nNumOfElements > 0 && - target->nInternalPointer == HT_INVALID_IDX) { - idx = 0; - while (Z_TYPE(target->arData[idx].val) == IS_UNDEF) { - idx++; - } - target->nInternalPointer = idx; - } - } else if (source->u.flags & HASH_FLAG_PACKED) { - target->u.flags = (source->u.flags & ~HASH_FLAG_PERSISTENT) | HASH_FLAG_APPLY_PROTECTION; - target->nTableMask = source->nTableMask; - target->nNumUsed = source->nNumUsed; - target->nNumOfElements = source->nNumOfElements; - target->nNextFreeElement = source->nNextFreeElement; - if (ctxt->copy == APC_COPY_IN) { - HT_SET_DATA_ADDR(target, pool->palloc(pool, HT_SIZE(target))); - } else + target->nInternalPointer = source->nInternalPointer; + memcpy(HT_GET_DATA_ADDR(target), HT_GET_DATA_ADDR(source), HT_USED_SIZE(source)); + if (target->nNumOfElements > 0 && target->nInternalPointer == HT_INVALID_IDX) { + idx = 0; + while (Z_TYPE(target->arData[idx].val) == IS_UNDEF) { + idx++; + } + target->nInternalPointer = idx; + } + } else if (source->u.flags & HASH_FLAG_PACKED) { + target->u.flags = (source->u.flags & ~HASH_FLAG_PERSISTENT) | HASH_FLAG_APPLY_PROTECTION; + target->nTableMask = source->nTableMask; + target->nNumUsed = source->nNumUsed; + target->nNumOfElements = source->nNumOfElements; + target->nNextFreeElement = source->nNextFreeElement; + if (ctxt->copy == APC_COPY_IN) { + HT_SET_DATA_ADDR(target, pool->palloc(pool, HT_SIZE(target))); + } else HT_SET_DATA_ADDR(target, emalloc(HT_SIZE(target))); if (HT_GET_DATA_ADDR(target) == NULL) goto bad; - target->nInternalPointer = source->nInternalPointer; - HT_HASH_RESET_PACKED(target); - - if (target->nNumUsed == target->nNumOfElements) { - apc_array_dup_packed_elements(ctxt, source, target, 0); - } else { - apc_array_dup_packed_elements(ctxt, source, target, 1); - } - if (target->nNumOfElements > 0 && - target->nInternalPointer == HT_INVALID_IDX) { - idx = 0; - while (Z_TYPE(target->arData[idx].val) == IS_UNDEF) { - idx++; - } - target->nInternalPointer = idx; - } - } else { - target->u.flags = (source->u.flags & ~HASH_FLAG_PERSISTENT) | HASH_FLAG_APPLY_PROTECTION; - target->nTableMask = source->nTableMask; - target->nNextFreeElement = source->nNextFreeElement; - target->nInternalPointer = HT_INVALID_IDX; - if (ctxt->copy == APC_COPY_IN) { - HT_SET_DATA_ADDR(target, pool->palloc(pool, HT_SIZE(target))); - } else + target->nInternalPointer = source->nInternalPointer; + HT_HASH_RESET_PACKED(target); + + if (target->nNumUsed == target->nNumOfElements) { + apc_array_dup_packed_elements(ctxt, source, target, 0); + } else { + apc_array_dup_packed_elements(ctxt, source, target, 1); + } + if (target->nNumOfElements > 0 && target->nInternalPointer == HT_INVALID_IDX) { + idx = 0; + while (Z_TYPE(target->arData[idx].val) == IS_UNDEF) { + idx++; + } + target->nInternalPointer = idx; + } + } else { + target->u.flags = (source->u.flags & ~HASH_FLAG_PERSISTENT) | HASH_FLAG_APPLY_PROTECTION; + target->nTableMask = source->nTableMask; + target->nNextFreeElement = source->nNextFreeElement; + target->nInternalPointer = HT_INVALID_IDX; + if (ctxt->copy == APC_COPY_IN) { + HT_SET_DATA_ADDR(target, pool->palloc(pool, HT_SIZE(target))); + } else HT_SET_DATA_ADDR(target, emalloc(HT_SIZE(target))); if (HT_GET_DATA_ADDR(target) == NULL) goto bad; - HT_HASH_RESET(target); - - if (target->u.flags & HASH_FLAG_STATIC_KEYS) { - if (source->nNumUsed == source->nNumOfElements) { - idx = apc_array_dup_elements(ctxt, source, target, 1, 0); - } else { - idx = apc_array_dup_elements(ctxt, source, target, 1, 1); - } - } else { - if (source->nNumUsed == source->nNumOfElements) { - idx = apc_array_dup_elements(ctxt, source, target, 0, 0); - } else { - idx = apc_array_dup_elements(ctxt, source, target, 0, 1); - } - } - target->nNumUsed = idx; - target->nNumOfElements = idx; - if (idx > 0 && target->nInternalPointer == HT_INVALID_IDX) { - target->nInternalPointer = 0; - } - } - return target; - - bad: + HT_HASH_RESET(target); + + if (target->u.flags & HASH_FLAG_STATIC_KEYS) { + if (source->nNumUsed == source->nNumOfElements) { + idx = apc_array_dup_elements(ctxt, source, target, 1, 0); + } else { + idx = apc_array_dup_elements(ctxt, source, target, 1, 1); + } + } else { + if (source->nNumUsed == source->nNumOfElements) { + idx = apc_array_dup_elements(ctxt, source, target, 0, 0); + } else { + idx = apc_array_dup_elements(ctxt, source, target, 0, 1); + } + } + target->nNumUsed = idx; + target->nNumOfElements = idx; + if (idx > 0 && target->nInternalPointer == HT_INVALID_IDX) { + target->nInternalPointer = 0; + } + } + return target; + +bad: /* some kind of memory allocation failure */ if (target) { - if (ctxt->copy == APC_COPY_IN) { + if (ctxt->copy == APC_COPY_IN) { pool->pfree(pool, target); - } else { + } else { FREE_HASHTABLE(target); } } @@ -1481,19 +1540,21 @@ static APC_HOTSPOT HashTable* my_copy_hashtable(HashTable *source, apc_context_t return NULL; } -static APC_HOTSPOT zend_reference* my_copy_reference(const zend_reference* src, apc_context_t *ctxt) { - apc_pool* pool = ctxt->pool; - zend_reference *dst; +static APC_HOTSPOT zend_reference* +my_copy_reference(const zend_reference* src, apc_context_t* ctxt) +{ + apc_pool* pool = ctxt->pool; + zend_reference* dst; - assert(src != NULL); + assert(src != NULL); - if (ctxt->copied.nTableSize) { - zend_reference *rc = zend_hash_index_find_ptr(&ctxt->copied, (uintptr_t) src); - if (rc) { - GC_REFCOUNT(rc)++; - return rc; - } - } + if (ctxt->copied.nTableSize) { + zend_reference* rc = zend_hash_index_find_ptr(&ctxt->copied, (uintptr_t) src); + if (rc) { + GC_REFCOUNT(rc)++; + return rc; + } + } if (ctxt->copy == APC_COPY_IN) { dst = pool->palloc(pool, sizeof(zend_reference)); @@ -1504,44 +1565,45 @@ static APC_HOTSPOT zend_reference* my_copy_reference(const zend_reference* src, if (dst == NULL) return NULL; - GC_REFCOUNT(dst) = 1; + GC_REFCOUNT(dst) = 1; GC_TYPE_INFO(dst) = IS_REFERENCE; if (my_copy_zval(&dst->val, &src->val, ctxt) == NULL) { return NULL; } - if (ctxt->copied.nTableSize) { - zend_hash_index_update_ptr(&ctxt->copied, (uintptr_t) src, dst); - } + if (ctxt->copied.nTableSize) { + zend_hash_index_update_ptr(&ctxt->copied, (uintptr_t) src, dst); + } return dst; } /* {{{ my_copy_zval */ -/* This function initializes *dst (temporary zval with request lifetime) with the (possibly serialized) contents of the serialized value in *src */ -static APC_HOTSPOT zval* my_copy_zval(zval* dst, const zval* src, apc_context_t* ctxt) +/* This function initializes *dst (temporary zval with request lifetime) with the (possibly serialized) contents of the + * serialized value in *src */ +static APC_HOTSPOT zval* +my_copy_zval(zval* dst, const zval* src, apc_context_t* ctxt) { apc_pool* pool = ctxt->pool; assert(dst != NULL); assert(src != NULL); - /* If src was already unserialized, then make dst a copy of the unserialization of src */ - if (Z_REFCOUNTED_P(src)) { - if (zend_hash_num_elements(&ctxt->copied)) { - zval *rc = zend_hash_index_find( - &ctxt->copied, (uintptr_t) Z_COUNTED_P(src)); + /* If src was already unserialized, then make dst a copy of the unserialization of src */ + if (Z_REFCOUNTED_P(src)) { + if (zend_hash_num_elements(&ctxt->copied)) { + zval* rc = zend_hash_index_find(&ctxt->copied, (uintptr_t) Z_COUNTED_P(src)); if (rc) { /* this does not allocate memory, so always succeeds */ - ZVAL_COPY(dst, rc); - return dst; + ZVAL_COPY(dst, rc); + return dst; } - } - } + } + } - /* Copy the raw bytes of the type, value, and type flags */ - memcpy(dst, src, sizeof(zval)); + /* Copy the raw bytes of the type, value, and type flags */ + memcpy(dst, src, sizeof(zval)); switch (Z_TYPE_P(src)) { case IS_RESOURCE: @@ -1553,41 +1615,43 @@ static APC_HOTSPOT zval* my_copy_zval(zval* dst, const zval* src, apc_context_t* /* No additional work for scalars, they aren't ref counted */ break; - case IS_REFERENCE: - if ((Z_REF_P(dst) = my_copy_reference(Z_REF_P(src), ctxt)) == NULL) + case IS_REFERENCE: + if ((Z_REF_P(dst) = my_copy_reference(Z_REF_P(src), ctxt)) == NULL) return NULL; - break; + break; - case IS_INDIRECT: - if (my_copy_zval(dst, Z_INDIRECT_P(src), ctxt) == NULL) + case IS_INDIRECT: + if (my_copy_zval(dst, Z_INDIRECT_P(src), ctxt) == NULL) return NULL; - break; + break; case IS_CONSTANT: - case IS_STRING: - if (ctxt->copy == APC_COPY_OUT) { - ZVAL_DUP(dst, src); - } else { - Z_TYPE_INFO_P(dst) = IS_STRING_EX; - Z_STR_P(dst) = apc_pstrcpy(Z_STR_P(src), pool); - } + case IS_STRING: + if (ctxt->copy == APC_COPY_OUT) { + ZVAL_DUP(dst, src); + } else { + Z_TYPE_INFO_P(dst) = IS_STRING_EX; + Z_STR_P(dst) = apc_pstrcpy(Z_STR_P(src), pool); + } if (Z_STR_P(dst) == NULL) return NULL; break; case IS_ARRAY: - if(ctxt->serializer == NULL) { - if ((Z_ARRVAL_P(dst) = my_copy_hashtable(Z_ARRVAL_P(src), ctxt)) == NULL) + if (ctxt->serializer == NULL) { + if ((Z_ARRVAL_P(dst) = my_copy_hashtable(Z_ARRVAL_P(src), ctxt)) == NULL) return NULL; break; } - /* break intentionally omitted */ + /* break intentionally omitted */ case IS_OBJECT: if (ctxt->copy == APC_COPY_IN) { - /* For objects and arrays, their pointer points to a serialized string instead of a zend_array or zend_object. */ - /* Unserialize that, and on success, give dst the default type flags for an object/array (We check Z_REFCOUNTED_P below). */ + /* For objects and arrays, their pointer points to a serialized string instead of a zend_array or + * zend_object. */ + /* Unserialize that, and on success, give dst the default type flags for an object/array (We check + * Z_REFCOUNTED_P below). */ dst = my_serialize_object(dst, src, ctxt); } else dst = my_unserialize_object(dst, src, ctxt); @@ -1599,23 +1663,25 @@ static APC_HOTSPOT zval* my_copy_zval(zval* dst, const zval* src, apc_context_t* assert(0); } - if (Z_REFCOUNTED_P(dst) && ctxt->copied.nTableSize) { - zend_hash_index_update(&ctxt->copied, (uintptr_t) Z_COUNTED_P(src), dst); - } + if (Z_REFCOUNTED_P(dst) && ctxt->copied.nTableSize) { + zend_hash_index_update(&ctxt->copied, (uintptr_t) Z_COUNTED_P(src), dst); + } return dst; } /* }}} */ /* {{{ apc_copy_zval */ -PHP_APCU_API zval* apc_copy_zval(zval* dst, const zval* src, apc_context_t* ctxt) +PHP_APCU_API zval* +apc_copy_zval(zval* dst, const zval* src, apc_context_t* ctxt) { return my_copy_zval(dst, src, ctxt); } /* }}} */ /* {{{ apc_cache_store_zval */ -PHP_APCU_API zval* apc_cache_store_zval(zval* dst, const zval* src, apc_context_t* ctxt) +PHP_APCU_API zval* +apc_cache_store_zval(zval* dst, const zval* src, apc_context_t* ctxt) { if (Z_TYPE_P(src) == IS_ARRAY) { /* Maintain a list of zvals we've copied to properly handle recursive structures */ @@ -1623,21 +1689,22 @@ PHP_APCU_API zval* apc_cache_store_zval(zval* dst, const zval* src, apc_context_ dst = apc_copy_zval(dst, src, ctxt); /* remove from copied regardless if allocation failure */ zend_hash_destroy(&ctxt->copied); - ctxt->copied.nTableSize=0; + ctxt->copied.nTableSize = 0; } else { dst = apc_copy_zval(dst, src, ctxt); } - if (dst == NULL || EG(exception)) { - return NULL; - } + if (dst == NULL || EG(exception)) { + return NULL; + } return dst; } /* }}} */ /* {{{ apc_cache_fetch_zval */ -PHP_APCU_API zval* apc_cache_fetch_zval(apc_context_t* ctxt, zval* dst, const zval* src) +PHP_APCU_API zval* +apc_cache_fetch_zval(apc_context_t* ctxt, zval* dst, const zval* src) { if (Z_TYPE_P(src) == IS_ARRAY) { /* Maintain a list of zvals we've copied to properly handle recursive structures */ @@ -1645,7 +1712,7 @@ PHP_APCU_API zval* apc_cache_fetch_zval(apc_context_t* ctxt, zval* dst, const zv dst = apc_copy_zval(dst, src, ctxt); /* remove from copied regardless if allocation failure */ zend_hash_destroy(&ctxt->copied); - ctxt->copied.nTableSize=0; + ctxt->copied.nTableSize = 0; } else { dst = apc_copy_zval(dst, src, ctxt); } @@ -1655,34 +1722,36 @@ PHP_APCU_API zval* apc_cache_fetch_zval(apc_context_t* ctxt, zval* dst, const zv /* }}} */ /* {{{ apc_cache_make_entry */ -PHP_APCU_API apc_cache_entry_t* apc_cache_make_entry(apc_context_t* ctxt, apc_cache_key_t *key, const zval* val, const int32_t ttl) +PHP_APCU_API apc_cache_entry_t* +apc_cache_make_entry(apc_context_t* ctxt, apc_cache_key_t* key, const zval* val, const int32_t ttl) { apc_cache_entry_t* entry; apc_pool* pool = ctxt->pool; entry = (apc_cache_entry_t*) pool->palloc(pool, sizeof(apc_cache_entry_t)); if (!entry) { - return NULL; - } - - /* set key for serializer */ - ctxt->key = key; - + return NULL; + } + + /* set key for serializer */ + ctxt->key = key; + if (!apc_cache_store_zval(&entry->val, val, ctxt)) { pool->pfree(pool, entry); return NULL; } - entry->ttl = ttl; + entry->ttl = ttl; entry->ref_count = 0; - entry->mem_size = 0; - entry->pool = pool; + entry->mem_size = 0; + entry->pool = pool; return entry; } /* }}} */ /* {{{ apc_cache_link_info */ -static zval apc_cache_link_info(apc_cache_t *cache, apc_cache_slot_t* p) +static zval +apc_cache_link_info(apc_cache_t* cache, apc_cache_slot_t* p) { zval link; @@ -1691,7 +1760,7 @@ static zval apc_cache_link_info(apc_cache_t *cache, apc_cache_slot_t* p) add_assoc_str(&link, "info", zend_string_dup(p->key.str, 0)); add_assoc_long(&link, "ttl", p->value->ttl); - add_assoc_double(&link, "num_hits", (double)p->nhits); + add_assoc_double(&link, "num_hits", (double) p->nhits); add_assoc_long(&link, "mtime", p->key.mtime); add_assoc_long(&link, "creation_time", p->ctime); add_assoc_long(&link, "deletion_time", p->dtime); @@ -1704,13 +1773,14 @@ static zval apc_cache_link_info(apc_cache_t *cache, apc_cache_slot_t* p) /* }}} */ #if APC_MMAP -#define apc_cache_info_set_memory_type() add_assoc_stringl(&info, "memory_type", "mmap", sizeof("mmap")-1) +#define apc_cache_info_set_memory_type() add_assoc_stringl(&info, "memory_type", "mmap", sizeof("mmap") - 1) #else -#define apc_cache_info_set_memory_type() add_assoc_stringl(&info, "memory_type", "IPC shared", sizeof("IPC shared")-1) +#define apc_cache_info_set_memory_type() add_assoc_stringl(&info, "memory_type", "IPC shared", sizeof("IPC shared") - 1) #endif /* {{{ apc_cache_info */ -PHP_APCU_API zval apc_cache_info(apc_cache_t* cache, zend_bool limited) +PHP_APCU_API zval +apc_cache_info(apc_cache_t* cache, zend_bool limited) { zval info; zval list; @@ -1720,58 +1790,60 @@ PHP_APCU_API zval apc_cache_info(apc_cache_t* cache, zend_bool limited) zend_ulong i, j; if (!cache) { - ZVAL_NULL(&info); + ZVAL_NULL(&info); return info; } - php_apc_try(APC_RLOCK(cache->header), { - - array_init(&info); - add_assoc_long(&info, "num_slots", cache->nslots); - add_assoc_long(&info, "ttl", cache->ttl); - add_assoc_double(&info, "num_hits", (double)cache->header->nhits); - add_assoc_double(&info, "num_misses", (double)cache->header->nmisses); - add_assoc_double(&info, "num_inserts", (double)cache->header->ninserts); - add_assoc_long(&info, "num_entries", cache->header->nentries); - add_assoc_double(&info, "expunges", (double)cache->header->nexpunges); - add_assoc_long(&info, "start_time", cache->header->stime); - add_assoc_double(&info, "mem_size", (double)cache->header->mem_size); - - apc_cache_info_set_memory_type(); - - if (!limited) { - /* For each hashtable slot */ - array_init(&list); - array_init(&slots); - - for (i = 0; i < cache->nslots; i++) { - p = cache->slots[i]; - j = 0; - for (; p != NULL; p = p->next) { - zval link = apc_cache_link_info(cache, p); - add_next_index_zval(&list, &link); - j++; - } - if(j != 0) { - add_index_long(&slots, (ulong)i, j); - } - } - - /* For each slot pending deletion */ - array_init(&gc); - - for (p = cache->header->gc; p != NULL; p = p->next) { - zval link = apc_cache_link_info(cache, p); - add_next_index_zval(&gc, &link); - } - - add_assoc_zval(&info, "cache_list", &list); - add_assoc_zval(&info, "deleted_list", &gc); - add_assoc_zval(&info, "slot_distribution", &slots); - } - - }, APC_RUNLOCK(cache->header)); + php_apc_try(APC_RLOCK(cache->header), + { + + array_init(&info); + add_assoc_long(&info, "num_slots", cache->nslots); + add_assoc_long(&info, "ttl", cache->ttl); + add_assoc_double(&info, "num_hits", (double) cache->header->nhits); + add_assoc_double(&info, "num_misses", (double) cache->header->nmisses); + add_assoc_double(&info, "num_inserts", (double) cache->header->ninserts); + add_assoc_long(&info, "num_entries", cache->header->nentries); + add_assoc_double(&info, "expunges", (double) cache->header->nexpunges); + add_assoc_long(&info, "start_time", cache->header->stime); + add_assoc_double(&info, "mem_size", (double) cache->header->mem_size); + + apc_cache_info_set_memory_type(); + + if (!limited) { + /* For each hashtable slot */ + array_init(&list); + array_init(&slots); + + for (i = 0; i < cache->nslots; i++) { + p = cache->slots[i]; + j = 0; + for (; p != NULL; p = p->next) { + zval link = apc_cache_link_info(cache, p); + add_next_index_zval(&list, &link); + j++; + } + if (j != 0) { + add_index_long(&slots, (ulong) i, j); + } + } + + /* For each slot pending deletion */ + array_init(&gc); + + for (p = cache->header->gc; p != NULL; p = p->next) { + zval link = apc_cache_link_info(cache, p); + add_next_index_zval(&gc, &link); + } + + add_assoc_zval(&info, "cache_list", &list); + add_assoc_zval(&info, "deleted_list", &gc); + add_assoc_zval(&info, "slot_distribution", &slots); + } + + }, + APC_RUNLOCK(cache->header)); return info; } @@ -1781,156 +1853,177 @@ PHP_APCU_API zval apc_cache_info(apc_cache_t* cache, zend_bool limited) /* fetches information about the key provided */ -PHP_APCU_API zval* apc_cache_stat(apc_cache_t* cache, zend_string *key, zval *stat) { +PHP_APCU_API zval* +apc_cache_stat(apc_cache_t* cache, zend_string* key, zval* stat) +{ apc_cache_slot_t** slot; - zend_ulong h, s; - - /* calculate hash and slot */ - apc_cache_hash_slot(cache, key, &h, &s); - - php_apc_try(APC_RLOCK(cache->header), { - /* find head */ - slot = &cache->slots[s]; - - while (*slot) { - /* check for a matching key by has and identifier */ - if ((h == ZSTR_HASH((*slot)->key.str)) && - memcmp(ZSTR_VAL((*slot)->key.str), ZSTR_VAL(key), ZSTR_LEN(key)) == SUCCESS) { - array_init(stat); - - add_assoc_long(stat, "hits", (*slot)->nhits); - add_assoc_long(stat, "access_time", (*slot)->atime); - add_assoc_long(stat, "mtime", (*slot)->key.mtime); - add_assoc_long(stat, "creation_time", (*slot)->ctime); - add_assoc_long(stat, "deletion_time", (*slot)->dtime); - add_assoc_long(stat, "ttl", (*slot)->value->ttl); - add_assoc_long(stat, "refs", (*slot)->value->ref_count); - - break; - } - - /* next */ - slot = &(*slot)->next; - } - }, APC_RUNLOCK(cache->header)); + zend_ulong h, s; + + /* calculate hash and slot */ + apc_cache_hash_slot(cache, key, &h, &s); + + php_apc_try(APC_RLOCK(cache->header), + { + /* find head */ + slot = &cache->slots[s]; + + while (*slot) { + /* check for a matching key by has and identifier */ + if ((h == ZSTR_HASH((*slot)->key.str)) && + memcmp(ZSTR_VAL((*slot)->key.str), ZSTR_VAL(key), ZSTR_LEN(key)) == SUCCESS) { + array_init(stat); + + add_assoc_long(stat, "hits", (*slot)->nhits); + add_assoc_long(stat, "access_time", (*slot)->atime); + add_assoc_long(stat, "mtime", (*slot)->key.mtime); + add_assoc_long(stat, "creation_time", (*slot)->ctime); + add_assoc_long(stat, "deletion_time", (*slot)->dtime); + add_assoc_long(stat, "ttl", (*slot)->value->ttl); + add_assoc_long(stat, "refs", (*slot)->value->ref_count); + + break; + } + + /* next */ + slot = &(*slot)->next; + } + }, + APC_RUNLOCK(cache->header)); return stat; } /* {{{ apc_cache_busy */ -PHP_APCU_API zend_bool apc_cache_busy(apc_cache_t* cache) -{ - return (cache->header->state & APC_CACHE_ST_BUSY); +PHP_APCU_API zend_bool +apc_cache_busy(apc_cache_t* cache) +{ + return (cache->header->state & APC_CACHE_ST_BUSY); } /* }}} */ /* {{{ apc_cache_defense */ -PHP_APCU_API zend_bool apc_cache_defense(apc_cache_t* cache, apc_cache_key_t* key) +PHP_APCU_API zend_bool +apc_cache_defense(apc_cache_t* cache, apc_cache_key_t* key) { - zend_bool result = 0; + zend_bool result = 0; #ifdef ZTS -# define FROM_DIFFERENT_THREAD(k) ((key->owner = TSRMLS_CACHE) != (k)->owner) +#define FROM_DIFFERENT_THREAD(k) ((key->owner = TSRMLS_CACHE) != (k)->owner) #else -# define FROM_DIFFERENT_THREAD(k) ((key->owner = getpid()) != (k)->owner) +#define FROM_DIFFERENT_THREAD(k) ((key->owner = getpid()) != (k)->owner) #endif - /* only continue if slam defense is enabled */ - if (cache->defend) { - - /* for copy of locking key struct */ - apc_cache_key_t *last = &cache->header->lastkey; - - if (!last->str) { - return 0; - } - - /* check the hash and length match */ - if(ZSTR_HASH(last->str) == ZSTR_HASH(key->str) && ZSTR_LEN(last->str) == ZSTR_LEN(key->str)) { - /* check the time ( last second considered slam ) and context */ - if(last->mtime == key->mtime && FROM_DIFFERENT_THREAD(last)) { - /* potential cache slam */ - apc_debug( - "Potential cache slam averted for key '%s'", key->str); - result = 1; - } else { - /* sets enough information for an educated guess, but is not exact */ - last->str = key->str; - last->mtime = apc_time(); - - /* required to tell contexts apart */ + /* only continue if slam defense is enabled */ + if (cache->defend) { + + /* for copy of locking key struct */ + apc_cache_key_t* last = &cache->header->lastkey; + + if (!last->str) { + return 0; + } + + /* check the hash and length match */ + if (ZSTR_HASH(last->str) == ZSTR_HASH(key->str) && ZSTR_LEN(last->str) == ZSTR_LEN(key->str)) { + /* check the time ( last second considered slam ) and context */ + if (last->mtime == key->mtime && FROM_DIFFERENT_THREAD(last)) { + /* potential cache slam */ + apc_debug("Potential cache slam averted for key '%s'", key->str); + result = 1; + } else { + /* sets enough information for an educated guess, but is not exact */ + last->str = key->str; + last->mtime = apc_time(); + +/* required to tell contexts apart */ #ifdef ZTS - last->owner = TSRMLS_CACHE; + last->owner = TSRMLS_CACHE; #else - last->owner = getpid(); -#endif - } - } - } + last->owner = getpid(); +#endif + } + } + } return result; } /* }}} */ /* {{{ apc_cache_serializer */ -PHP_APCU_API void apc_cache_serializer(apc_cache_t* cache, const char* name) { - if (cache && !cache->serializer) { - cache->serializer = apc_find_serializer(name); - } +PHP_APCU_API void +apc_cache_serializer(apc_cache_t* cache, const char* name) +{ + if (cache && !cache->serializer) { + cache->serializer = apc_find_serializer(name); + } } /* }}} */ #ifndef APC_LOCK_RECURSIVE -# define apc_cache_entry_try_begin() { \ - if (APCG(recursion)++ == 0) { \ - APC_LOCK(cache->header); \ - } \ -} +#define apc_cache_entry_try_begin() \ + { \ + if (APCG(recursion)++ == 0) { \ + APC_LOCK(cache->header); \ + } \ + } -# define apc_cache_entry_try_end() { \ - if (--APCG(recursion) == 0) { \ - APC_UNLOCK(cache->header); \ - } \ -} +#define apc_cache_entry_try_end() \ + { \ + if (--APCG(recursion) == 0) { \ + APC_UNLOCK(cache->header); \ + } \ + } #else -# define apc_cache_entry_try_begin() APC_LOCK(cache->header); -# define apc_cache_entry_try_end() APC_UNLOCK(cache->header); +#define apc_cache_entry_try_begin() APC_LOCK(cache->header); +#define apc_cache_entry_try_end() APC_UNLOCK(cache->header); #endif -PHP_APCU_API void apc_cache_entry(apc_cache_t *cache, zval *key, zend_fcall_info *fci, zend_fcall_info_cache *fcc, zend_long ttl, zend_long now, zval *return_value) {/*{{{*/ - apc_cache_entry_t *entry = NULL; +PHP_APCU_API void +apc_cache_entry(apc_cache_t* cache, + zval* key, + zend_fcall_info* fci, + zend_fcall_info_cache* fcc, + zend_long ttl, + zend_long now, + zval* return_value) +{ /*{{{*/ + apc_cache_entry_t* entry = NULL; + + if (!cache || apc_cache_busy(cache)) { + return; + } - if(!cache || apc_cache_busy(cache)) { + if (!key || Z_TYPE_P(key) != IS_STRING) { + /* only strings, for now */ return; } - if (!key || Z_TYPE_P(key) != IS_STRING) { - /* only strings, for now */ - return; - } - - php_apc_try(apc_cache_entry_try_begin(), { - entry = apc_cache_find_internal(cache, Z_STR_P(key), now, 0); - if (!entry) { - int result = 0; - - fci->retval = return_value; - zend_fcall_info_argn(fci, 1, key); - - zend_try { - result = zend_call_function(fci, fcc); - } zend_end_try (); - - if (result == SUCCESS) { - zend_fcall_info_args_clear(fci, 1); - - if (!EG(exception)) { - apc_cache_store_internal( - cache, Z_STR_P(key), return_value, (uint32_t) ttl, 1); - } - } - } else apc_cache_fetch_internal(cache, Z_STR_P(key), entry, now, &return_value); - }, apc_cache_entry_try_begin()); -}/*}}}*/ + php_apc_try(apc_cache_entry_try_begin(), + { + entry = apc_cache_find_internal(cache, Z_STR_P(key), now, 0); + if (!entry) { + int result = 0; + + fci->retval = return_value; + zend_fcall_info_argn(fci, 1, key); + + zend_try + { + result = zend_call_function(fci, fcc); + } + zend_end_try(); + + if (result == SUCCESS) { + zend_fcall_info_args_clear(fci, 1); + + if (!EG(exception)) { + apc_cache_store_internal(cache, Z_STR_P(key), return_value, (uint32_t) ttl, 1); + } + } + } else + apc_cache_fetch_internal(cache, Z_STR_P(key), entry, now, &return_value); + }, + apc_cache_entry_try_begin()); +} /*}}}*/ #undef apc_cache_entry_try_begin #undef apc_cache_entry_try_end diff --git a/apc_cache.h b/apc_cache.h index f836012a..c603b695 100644 --- a/apc_cache.h +++ b/apc_cache.h @@ -37,7 +37,7 @@ #include "TSRM.h" #ifndef APC_CACHE_API_H -# include "apc_cache_api.h" +#include "apc_cache_api.h" #endif #endif diff --git a/apc_cache_api.h b/apc_cache_api.h index 5b5c6f04..e630544f 100644 --- a/apc_cache_api.h +++ b/apc_cache_api.h @@ -41,19 +41,19 @@ typedef pid_t apc_cache_owner_t; /* {{{ struct definition: apc_cache_key_t */ typedef struct apc_cache_key_t apc_cache_key_t; struct apc_cache_key_t { - zend_string *str; /* the key for this cached entry */ - time_t mtime; /* the mtime of this cached entry */ - apc_cache_owner_t owner; /* the context that created this key */ -}; /* }}} */ + zend_string* str; /* the key for this cached entry */ + time_t mtime; /* the mtime of this cached entry */ + apc_cache_owner_t owner; /* the context that created this key */ +}; /* }}} */ /* {{{ struct definition: apc_cache_entry_t */ typedef struct apc_cache_entry_t apc_cache_entry_t; struct apc_cache_entry_t { - zval val; /* the zval copied at store time */ - zend_long ttl; /* the ttl on this specific entry */ - zend_long ref_count;/* the reference count of this entry */ - zend_long mem_size; /* memory used */ - apc_pool *pool; /* pool which allocated the value */ + zval val; /* the zval copied at store time */ + zend_long ttl; /* the ttl on this specific entry */ + zend_long ref_count; /* the reference count of this entry */ + zend_long mem_size; /* memory used */ + apc_pool* pool; /* pool which allocated the value */ }; /* }}} */ @@ -61,35 +61,35 @@ struct apc_cache_entry_t { ition: apc_cache_slot_t */ typedef struct apc_cache_slot_t apc_cache_slot_t; struct apc_cache_slot_t { - apc_cache_key_t key; /* slot key */ - apc_cache_entry_t* value; /* slot value */ - apc_cache_slot_t* next; /* next slot in linked list */ - zend_long nhits; /* number of hits to this slot */ - time_t ctime; /* time slot was initialized */ - time_t dtime; /* time slot was removed from cache */ - time_t atime; /* time slot was last accessed */ + apc_cache_key_t key; /* slot key */ + apc_cache_entry_t* value; /* slot value */ + apc_cache_slot_t* next; /* next slot in linked list */ + zend_long nhits; /* number of hits to this slot */ + time_t ctime; /* time slot was initialized */ + time_t dtime; /* time slot was removed from cache */ + time_t atime; /* time slot was last accessed */ }; /* }}} */ /* {{{ state constants */ -#define APC_CACHE_ST_NONE 0 -#define APC_CACHE_ST_BUSY 0x00000001 /* }}} */ +#define APC_CACHE_ST_NONE 0 +#define APC_CACHE_ST_BUSY 0x00000001 /* }}} */ /* {{{ struct definition: apc_cache_header_t Any values that must be shared among processes should go in here. */ typedef struct _apc_cache_header_t { - apc_lock_t lock; /* header lock */ - zend_long nhits; /* hit count */ - zend_long nmisses; /* miss count */ - zend_long ninserts; /* insert count */ - zend_long nexpunges; /* expunge count */ - zend_long nentries; /* entry count */ - zend_long mem_size; /* used */ - time_t stime; /* start time */ - unsigned short state; /* cache state */ - apc_cache_key_t lastkey; /* last key inserted (not necessarily without error) */ - apc_cache_slot_t* gc; /* gc list */ -} apc_cache_header_t; /* }}} */ + apc_lock_t lock; /* header lock */ + zend_long nhits; /* hit count */ + zend_long nmisses; /* miss count */ + zend_long ninserts; /* insert count */ + zend_long nexpunges; /* expunge count */ + zend_long nentries; /* entry count */ + zend_long mem_size; /* used */ + time_t stime; /* start time */ + unsigned short state; /* cache state */ + apc_cache_key_t lastkey; /* last key inserted (not necessarily without error) */ + apc_cache_slot_t* gc; /* gc list */ +} apc_cache_header_t; /* }}} */ /* {{{ struct definition: apc_cache_t */ typedef struct _apc_cache_t { @@ -98,38 +98,38 @@ typedef struct _apc_cache_t { apc_cache_slot_t** slots; /* array of cache slots (stored in SHM) */ apc_sma_t* sma; /* shared memory allocator */ apc_serializer_t* serializer; /* serializer */ - zend_long nslots; /* number of slots in cache */ - zend_long gc_ttl; /* maximum time on GC list for a slot */ - zend_long ttl; /* if slot is needed and entry's access time is older than this ttl, remove it */ - zend_long smart; /* smart parameter for gc */ + zend_long nslots; /* number of slots in cache */ + zend_long gc_ttl; /* maximum time on GC list for a slot */ + zend_long ttl; /* if slot is needed and entry's access time is older than this ttl, remove it */ + zend_long smart; /* smart parameter for gc */ zend_bool defend; /* defense parameter for runtime */ -} apc_cache_t; /* }}} */ +} apc_cache_t; /* }}} */ /* {{{ typedef: apc_cache_updater_t */ typedef zend_bool (*apc_cache_updater_t)(apc_cache_t*, apc_cache_entry_t*, void* data); /* }}} */ /* - * apc_cache_create creates the shared memory cache. + * apc_cache_create creates the shared memory cache. * * This function should be called once per process per cache - * + * * serializer for APCu is set by globals on MINIT and ensured with apc_cache_serializer * during execution. Using apc_cache_serializer avoids race conditions between MINIT/RINIT of * APCU and the third party serializer. API users can choose to leave this null to use default * PHP serializers, or search the list of serializers for the preferred serializer * - * size_hint is a "hint" at the total number entries that will be expected. + * size_hint is a "hint" at the total number entries that will be expected. * It determines the physical size of the hash table. Passing 0 for * this argument will use a reasonable default value - * + * * gc_ttl is the maximum time a cache entry may speed on the garbage * collection list. This is basically a work around for the inherent * unreliability of our reference counting mechanism (see apc_cache_release). * * ttl is the maximum time a cache entry can idle in a slot in case the slot - * is needed. This helps in cleaning up the cache and ensuring that entries + * is needed. This helps in cleaning up the cache and ensuring that entries * hit frequently stay cached and ones not hit very often eventually disappear. - * + * * for an explanation of smart, see apc_cache_default_expunge * * defend enables/disables slam defense for this particular cache @@ -167,8 +167,8 @@ PHP_APCU_API void apc_cache_clear(apc_cache_t* cache); * an insert should happen in a shared context, a fetch should happen in a nonshared context */ PHP_APCU_API zend_bool apc_cache_make_context(apc_cache_t* cache, - apc_context_t* context, - apc_context_type context_type, + apc_context_t* context, + apc_context_type context_type, apc_pool_type pool_type, apc_copy_type copy_type, uint force_update); @@ -178,21 +178,21 @@ PHP_APCU_API zend_bool apc_cache_make_context(apc_cache_t* cache, */ PHP_APCU_API zend_bool apc_cache_make_context_ex(apc_context_t* context, apc_serializer_t* serializer, - apc_malloc_t _malloc, - apc_free_t _free, - apc_protect_t _protect, - apc_unprotect_t _unprotect, - apc_pool_type pool_type, - apc_copy_type copy_type, + apc_malloc_t _malloc, + apc_free_t _free, + apc_protect_t _protect, + apc_unprotect_t _unprotect, + apc_pool_type pool_type, + apc_copy_type copy_type, uint force_update); /* -* apc_context_destroy should be called when a context is finished being used +* apc_context_destroy should be called when a context is finished being used */ PHP_APCU_API zend_bool apc_cache_destroy_context(apc_context_t* context); /* * apc_cache_insert adds an entry to the cache. - * Returns true if the entry was successfully inserted, false otherwise. + * Returns true if the entry was successfully inserted, false otherwise. * If false is returned, the caller must free the cache entry by calling * apc_cache_free_entry (see below). * @@ -203,37 +203,34 @@ PHP_APCU_API zend_bool apc_cache_destroy_context(apc_context_t* context); * an easier API exists in the form of apc_cache_store */ PHP_APCU_API zend_bool apc_cache_insert(apc_cache_t* cache, - apc_cache_key_t* key, - apc_cache_entry_t* value, - apc_context_t* ctxt, - time_t t, - zend_bool exclusive); + apc_cache_key_t* key, + apc_cache_entry_t* value, + apc_context_t* ctxt, + time_t t, + zend_bool exclusive); /* * apc_cache_store creates key, entry and context in which to make an insertion of val into the specified cache */ -PHP_APCU_API zend_bool apc_cache_store(apc_cache_t* cache, - zend_string *key, - const zval *val, - const int32_t ttl, - const zend_bool exclusive); +PHP_APCU_API zend_bool +apc_cache_store(apc_cache_t* cache, zend_string* key, const zval* val, const int32_t ttl, const zend_bool exclusive); /* * apc_cache_update updates an entry in place, this is used for inc/dec/cas */ -PHP_APCU_API zend_bool apc_cache_update(apc_cache_t* cache, zend_string *key, apc_cache_updater_t updater, void* data); +PHP_APCU_API zend_bool apc_cache_update(apc_cache_t* cache, zend_string* key, apc_cache_updater_t updater, void* data); /* * apc_cache_find searches for a cache entry by its hashed identifier, * and returns a pointer to the entry if found, NULL otherwise. * */ -PHP_APCU_API apc_cache_entry_t* apc_cache_find(apc_cache_t* cache, zend_string *key, time_t t); +PHP_APCU_API apc_cache_entry_t* apc_cache_find(apc_cache_t* cache, zend_string* key, time_t t); /* * apc_cache_fetch fetches an entry from the cache directly into dst * */ -PHP_APCU_API zend_bool apc_cache_fetch(apc_cache_t* cache, zend_string *key, time_t t, zval **dst); +PHP_APCU_API zend_bool apc_cache_fetch(apc_cache_t* cache, zend_string* key, time_t t, zval** dst); /* * apc_cache_exists searches for a cache entry by its hashed identifier, @@ -242,12 +239,12 @@ PHP_APCU_API zend_bool apc_cache_fetch(apc_cache_t* cache, zend_string *key, tim * shared memory segment in any way. * */ -PHP_APCU_API apc_cache_entry_t* apc_cache_exists(apc_cache_t* cache, zend_string *key, time_t t); +PHP_APCU_API apc_cache_entry_t* apc_cache_exists(apc_cache_t* cache, zend_string* key, time_t t); /* * apc_cache_delete and apc_cache_delete finds an entry in the cache and deletes it. */ -PHP_APCU_API zend_bool apc_cache_delete(apc_cache_t* cache, zend_string *key); +PHP_APCU_API zend_bool apc_cache_delete(apc_cache_t* cache, zend_string* key); /* apc_cach_fetch_zval takes a zval in the cache and reconstructs a runtime * zval from it. @@ -269,25 +266,23 @@ PHP_APCU_API void apc_cache_release(apc_cache_t* cache, apc_cache_entry_t* entry /* * apc_cache_make_key creates an apc_cache_key_t from an identifier, it's length and the current time */ -PHP_APCU_API zend_bool apc_cache_make_key(apc_cache_key_t* key, zend_string *str); +PHP_APCU_API zend_bool apc_cache_make_key(apc_cache_key_t* key, zend_string* str); /* * apc_cache_make_entry creates an apc_cache_entry_t given a zval, context and ttl */ -PHP_APCU_API apc_cache_entry_t* apc_cache_make_entry(apc_context_t* ctxt, - apc_cache_key_t* key, - const zval *val, - const int32_t ttl); +PHP_APCU_API apc_cache_entry_t* +apc_cache_make_entry(apc_context_t* ctxt, apc_cache_key_t* key, const zval* val, const int32_t ttl); /* fetches information about the cache provided for userland status functions */ PHP_APCU_API zval apc_cache_info(apc_cache_t* cache, zend_bool limited); - + /* fetches information about the key provided */ -PHP_APCU_API zval* apc_cache_stat(apc_cache_t* cache, zend_string *key, zval *stat); +PHP_APCU_API zval* apc_cache_stat(apc_cache_t* cache, zend_string* key, zval* stat); /* * apc_cache_busy returns true while the cache is busy @@ -321,7 +316,7 @@ PHP_APCU_API void apc_cache_serializer(apc_cache_t* cache, const char* name); /* * The remaining functions allow a third party to reimplement expunge -* +* * Look at the source of apc_cache_default_expunge for what is expected of this function * * The default behaviour of expunge is explained below, should no combination of those options @@ -329,7 +324,7 @@ PHP_APCU_API void apc_cache_serializer(apc_cache_t* cache, const char* name); * call to apc_sma_api_impl, this will replace the default functionality. * The functions below you can use during your own implementation of expunge to gain more * control over how the expunge process works ... -* +* * Note: beware of locking (copy it exactly), setting states is also important */ @@ -387,7 +382,13 @@ PHP_APCU_API void apc_cache_remove_slot(apc_cache_t* cache, apc_cache_slot_t** s * * @see https://github.com/krakjoe/apcu/issues/142 */ -PHP_APCU_API void apc_cache_entry(apc_cache_t *cache, zval *key, zend_fcall_info *fci, zend_fcall_info_cache *fcc, zend_long ttl, zend_long now, zval *return_value); +PHP_APCU_API void apc_cache_entry(apc_cache_t* cache, + zval* key, + zend_fcall_info* fci, + zend_fcall_info_cache* fcc, + zend_long ttl, + zend_long now, + zval* return_value); #endif diff --git a/apc_globals.h b/apc_globals.h index a0de2340..065060de 100644 --- a/apc_globals.h +++ b/apc_globals.h @@ -39,41 +39,41 @@ #include "apc_stack.h" ZEND_BEGIN_MODULE_GLOBALS(apcu) - /* configuration parameters */ - zend_bool enabled; /* if true, apc is enabled (defaults to true) */ - zend_long shm_segments; /* number of shared memory segments to use */ - zend_long shm_size; /* size of each shared memory segment (in MB) */ - zend_long entries_hint; /* hint at the number of entries expected */ - zend_long gc_ttl; /* parameter to apc_cache_create */ - zend_long ttl; /* parameter to apc_cache_create */ - zend_long smart; /* smart value */ +/* configuration parameters */ +zend_bool enabled; /* if true, apc is enabled (defaults to true) */ +zend_long shm_segments; /* number of shared memory segments to use */ +zend_long shm_size; /* size of each shared memory segment (in MB) */ +zend_long entries_hint; /* hint at the number of entries expected */ +zend_long gc_ttl; /* parameter to apc_cache_create */ +zend_long ttl; /* parameter to apc_cache_create */ +zend_long smart; /* smart value */ #if APC_MMAP - char *mmap_file_mask; /* mktemp-style file-mask to pass to mmap */ +char* mmap_file_mask; /* mktemp-style file-mask to pass to mmap */ #endif - /* module variables */ - zend_bool initialized; /* true if module was initialized */ - zend_bool enable_cli; /* Flag to override turning APC off for CLI */ - zend_bool slam_defense; /* true for user cache slam defense */ +/* module variables */ +zend_bool initialized; /* true if module was initialized */ +zend_bool enable_cli; /* Flag to override turning APC off for CLI */ +zend_bool slam_defense; /* true for user cache slam defense */ - char *preload_path; /* preload path */ - zend_bool coredump_unmap; /* trap signals that coredump and unmap shared memory */ - zend_bool use_request_time; /* use the SAPI request start time for TTL */ +char* preload_path; /* preload path */ +zend_bool coredump_unmap; /* trap signals that coredump and unmap shared memory */ +zend_bool use_request_time; /* use the SAPI request start time for TTL */ - char *serializer_name; /* the serializer config option */ - char *writable; /* writable path for general use */ +char* serializer_name; /* the serializer config option */ +char* writable; /* writable path for general use */ - volatile zend_bool recursion; +volatile zend_bool recursion; ZEND_END_MODULE_GLOBALS(apcu) /* (the following is defined in php_apc.c) */ ZEND_EXTERN_MODULE_GLOBALS(apcu) #ifdef ZTS -# define APCG(v) TSRMG(apcu_globals_id, zend_apcu_globals *, v) +#define APCG(v) TSRMG(apcu_globals_id, zend_apcu_globals*, v) #else -# define APCG(v) (apcu_globals.v) +#define APCG(v) (apcu_globals.v) #endif extern apc_cache_t* apc_user_cache; diff --git a/apc_iterator.c b/apc_iterator.c index cbd25871..21b20aa3 100644 --- a/apc_iterator.c +++ b/apc_iterator.c @@ -27,36 +27,41 @@ #include "SAPI.h" #include "zend_interfaces.h" -static zend_class_entry *apc_iterator_ce; +static zend_class_entry* apc_iterator_ce; zend_object_handlers apc_iterator_object_handlers; -zend_class_entry* apc_iterator_get_ce(void) { - return apc_iterator_ce; +zend_class_entry* +apc_iterator_get_ce(void) +{ + return apc_iterator_ce; } /* {{{ apc_iterator_item */ -static apc_iterator_item_t* apc_iterator_item_ctor(apc_iterator_t *iterator, apc_cache_slot_t **slot_pp) { +static apc_iterator_item_t* +apc_iterator_item_ctor(apc_iterator_t* iterator, apc_cache_slot_t** slot_pp) +{ zval zvalue; - apc_cache_slot_t *slot = *slot_pp; - apc_context_t ctxt = {0, }; - apc_iterator_item_t *item = ecalloc(1, sizeof(apc_iterator_item_t)); + apc_cache_slot_t* slot = *slot_pp; + apc_context_t ctxt = { + 0, + }; + apc_iterator_item_t* item = ecalloc(1, sizeof(apc_iterator_item_t)); array_init(&item->value); - item->key = slot->key.str; + item->key = slot->key.str; if (APC_ITER_TYPE & iterator->format) { - add_assoc_string_ex(&item->value, "type", sizeof("type")-1, "user"); - } + add_assoc_string_ex(&item->value, "type", sizeof("type") - 1, "user"); + } - if (APC_ITER_KEY & iterator->format) { - add_assoc_str(&item->value, "key", zend_string_copy(item->key)); - } + if (APC_ITER_KEY & iterator->format) { + add_assoc_str(&item->value, "key", zend_string_copy(item->key)); + } if (APC_ITER_VALUE & iterator->format) { - apc_cache_make_context( - apc_user_cache, &ctxt, APC_CONTEXT_NOSHARE, APC_UNPOOL, APC_COPY_OUT, 0); - ZVAL_UNDEF(&zvalue); + apc_cache_make_context(apc_user_cache, &ctxt, APC_CONTEXT_NOSHARE, APC_UNPOOL, APC_COPY_OUT, 0); + ZVAL_UNDEF(&zvalue); apc_cache_fetch_zval(&ctxt, &zvalue, &slot->value->val); add_assoc_zval(&item->value, "value", &zvalue); apc_pool_destroy(ctxt.pool); @@ -92,25 +97,31 @@ static apc_iterator_item_t* apc_iterator_item_ctor(apc_iterator_t *iterator, apc /* }}} */ /* {{{ apc_iterator_clone */ -static zend_object* apc_iterator_clone(zval *zobject) { +static zend_object* +apc_iterator_clone(zval* zobject) +{ apc_error(APC_ITERATOR_NAME " object cannot be cloned"); return NULL; } /* }}} */ /* {{{ apc_iterator_item_dtor */ -static void apc_iterator_item_dtor(apc_iterator_item_t *item) { +static void +apc_iterator_item_dtor(apc_iterator_item_t* item) +{ zval_ptr_dtor(&item->value); efree(item); } /* }}} */ /* {{{ acp_iterator_free */ -static void apc_iterator_free(zend_object *object) { - apc_iterator_t *iterator = apc_iterator_fetch_from(object); +static void +apc_iterator_free(zend_object* object) +{ + apc_iterator_t* iterator = apc_iterator_fetch_from(object); if (iterator->initialized == 0) { - zend_object_std_dtor(object); + zend_object_std_dtor(object); return; } @@ -132,23 +143,24 @@ static void apc_iterator_free(zend_object *object) { } iterator->initialized = 0; - zend_object_std_dtor(object); + zend_object_std_dtor(object); } /* }}} */ /* {{{ apc_iterator_create */ -zend_object* apc_iterator_create(zend_class_entry *ce) { - apc_iterator_t *iterator = - (apc_iterator_t*) emalloc(sizeof(apc_iterator_t) + zend_object_properties_size(ce)); +zend_object* +apc_iterator_create(zend_class_entry* ce) +{ + apc_iterator_t* iterator = (apc_iterator_t*) emalloc(sizeof(apc_iterator_t) + zend_object_properties_size(ce)); zend_object_std_init(&iterator->obj, ce); object_properties_init(&iterator->obj, ce); - iterator->initialized = 0; - iterator->stack = NULL; - iterator->regex = NULL; - iterator->search_hash = NULL; - iterator->obj.handlers = &apc_iterator_object_handlers; + iterator->initialized = 0; + iterator->stack = NULL; + iterator->regex = NULL; + iterator->search_hash = NULL; + iterator->obj.handlers = &apc_iterator_object_handlers; return &iterator->obj; } @@ -157,12 +169,15 @@ zend_object* apc_iterator_create(zend_class_entry *ce) { /* {{{ apc_iterator_search_match * Verify if the key matches our search parameters */ -static int apc_iterator_search_match(apc_iterator_t *iterator, apc_cache_slot_t **slot) { +static int +apc_iterator_search_match(apc_iterator_t* iterator, apc_cache_slot_t** slot) +{ int rval = 1; #ifdef ITERATOR_PCRE if (iterator->regex) { - rval = (pcre_exec(iterator->re, NULL, ZSTR_VAL((*slot)->key.str), ZSTR_LEN((*slot)->key.str), 0, 0, NULL, 0) >= 0); + rval = + (pcre_exec(iterator->re, NULL, ZSTR_VAL((*slot)->key.str), ZSTR_LEN((*slot)->key.str), 0, 0, NULL, 0) >= 0); } #endif @@ -175,14 +190,15 @@ static int apc_iterator_search_match(apc_iterator_t *iterator, apc_cache_slot_t /* }}} */ /* {{{ apc_iterator_check_expiry */ -static int apc_iterator_check_expiry(apc_cache_t* cache, apc_cache_slot_t **slot, time_t t) +static int +apc_iterator_check_expiry(apc_cache_t* cache, apc_cache_slot_t** slot, time_t t) { - if((*slot)->value->ttl) { - if((time_t) ((*slot)->ctime + (*slot)->value->ttl) < t) { + if ((*slot)->value->ttl) { + if ((time_t)((*slot)->ctime + (*slot)->value->ttl) < t) { return 0; } - } else if(cache->ttl) { - if((*slot)->ctime + cache->ttl < t) { + } else if (cache->ttl) { + if ((*slot)->ctime + cache->ttl < t) { return 0; } } @@ -192,10 +208,12 @@ static int apc_iterator_check_expiry(apc_cache_t* cache, apc_cache_slot_t **slot /* }}} */ /* {{{ apc_iterator_fetch_active */ -static int apc_iterator_fetch_active(apc_iterator_t *iterator) { - int count=0; - apc_cache_slot_t **slot; - apc_iterator_item_t *item; +static int +apc_iterator_fetch_active(apc_iterator_t* iterator) +{ + int count = 0; + apc_cache_slot_t** slot; + apc_iterator_item_t* item; time_t t; t = apc_time(); @@ -204,90 +222,101 @@ static int apc_iterator_fetch_active(apc_iterator_t *iterator) { apc_iterator_item_dtor(apc_stack_pop(iterator->stack)); } - php_apc_try(APC_RLOCK(apc_user_cache->header), { - while(count <= iterator->chunk_size && iterator->slot_idx < apc_user_cache->nslots) { - slot = &apc_user_cache->slots[iterator->slot_idx]; - while(*slot) { - if (apc_iterator_check_expiry(apc_user_cache, slot, t)) { - if (apc_iterator_search_match(iterator, slot)) { - count++; - item = apc_iterator_item_ctor(iterator, slot); - if (item) { - apc_stack_push(iterator->stack, item); - } - } - } - slot = &(*slot)->next; - } - iterator->slot_idx++; - } - }, { - iterator->stack_idx = 0; - APC_RUNLOCK(apc_user_cache->header) - }); + php_apc_try(APC_RLOCK(apc_user_cache->header), + { + while (count <= iterator->chunk_size && iterator->slot_idx < apc_user_cache->nslots) { + slot = &apc_user_cache->slots[iterator->slot_idx]; + while (*slot) { + if (apc_iterator_check_expiry(apc_user_cache, slot, t)) { + if (apc_iterator_search_match(iterator, slot)) { + count++; + item = apc_iterator_item_ctor(iterator, slot); + if (item) { + apc_stack_push(iterator->stack, item); + } + } + } + slot = &(*slot)->next; + } + iterator->slot_idx++; + } + }, + { + iterator->stack_idx = 0; + APC_RUNLOCK(apc_user_cache->header) + }); return count; } /* }}} */ /* {{{ apc_iterator_fetch_deleted */ -static int apc_iterator_fetch_deleted(apc_iterator_t *iterator) { - int count=0; - apc_cache_slot_t **slot; - apc_iterator_item_t *item; - - php_apc_try(APC_RLOCK(apc_user_cache->header), { - slot = &apc_user_cache->header->gc; - while ((*slot) && count <= iterator->slot_idx) { - count++; - slot = &(*slot)->next; - } - count = 0; - while ((*slot) && count < iterator->chunk_size) { - if (apc_iterator_search_match(iterator, slot)) { - count++; - item = apc_iterator_item_ctor(iterator, slot); - if (item) { - apc_stack_push(iterator->stack, item); - } - } - slot = &(*slot)->next; - } - }, { - iterator->slot_idx += count; - iterator->stack_idx = 0; - APC_RUNLOCK(apc_user_cache->header); - }); +static int +apc_iterator_fetch_deleted(apc_iterator_t* iterator) +{ + int count = 0; + apc_cache_slot_t** slot; + apc_iterator_item_t* item; + + php_apc_try(APC_RLOCK(apc_user_cache->header), + { + slot = &apc_user_cache->header->gc; + while ((*slot) && count <= iterator->slot_idx) { + count++; + slot = &(*slot)->next; + } + count = 0; + while ((*slot) && count < iterator->chunk_size) { + if (apc_iterator_search_match(iterator, slot)) { + count++; + item = apc_iterator_item_ctor(iterator, slot); + if (item) { + apc_stack_push(iterator->stack, item); + } + } + slot = &(*slot)->next; + } + }, + { + iterator->slot_idx += count; + iterator->stack_idx = 0; + APC_RUNLOCK(apc_user_cache->header); + }); return count; } /* }}} */ /* {{{ apc_iterator_totals */ -static void apc_iterator_totals(apc_iterator_t *iterator) { - apc_cache_slot_t **slot; +static void +apc_iterator_totals(apc_iterator_t* iterator) +{ + apc_cache_slot_t** slot; int i; - php_apc_try(APC_RLOCK(apc_user_cache->header), { - for (i=0; i < apc_user_cache->nslots; i++) { - slot = &apc_user_cache->slots[i]; - while((*slot)) { - if (apc_iterator_search_match(iterator, slot)) { - iterator->size += (*slot)->value->mem_size; - iterator->hits += (*slot)->nhits; - iterator->count++; - } - slot = &(*slot)->next; - } - } - }, { - iterator->totals_flag = 1; - APC_RUNLOCK(apc_user_cache->header); - }); + php_apc_try(APC_RLOCK(apc_user_cache->header), + { + for (i = 0; i < apc_user_cache->nslots; i++) { + slot = &apc_user_cache->slots[i]; + while ((*slot)) { + if (apc_iterator_search_match(iterator, slot)) { + iterator->size += (*slot)->value->mem_size; + iterator->hits += (*slot)->nhits; + iterator->count++; + } + slot = &(*slot)->next; + } + } + }, + { + iterator->totals_flag = 1; + APC_RUNLOCK(apc_user_cache->header); + }); } /* }}} */ -void apc_iterator_obj_init(apc_iterator_t *iterator, zval *search, zend_long format, zend_long chunk_size, zend_long list) +void +apc_iterator_obj_init(apc_iterator_t* iterator, zval* search, zend_long format, zend_long chunk_size, zend_long list) { if (!APCG(enabled)) { apc_error("APC must be enabled to use " APC_ITERATOR_NAME); @@ -312,29 +341,30 @@ void apc_iterator_obj_init(apc_iterator_t *iterator, zval *search, zend_long for return; } - iterator->slot_idx = 0; - iterator->stack_idx = 0; - iterator->key_idx = 0; - iterator->chunk_size = chunk_size == 0 ? APC_DEFAULT_CHUNK_SIZE : chunk_size; - iterator->stack = apc_stack_create(chunk_size); - iterator->format = format; + iterator->slot_idx = 0; + iterator->stack_idx = 0; + iterator->key_idx = 0; + iterator->chunk_size = chunk_size == 0 ? APC_DEFAULT_CHUNK_SIZE : chunk_size; + iterator->stack = apc_stack_create(chunk_size); + iterator->format = format; iterator->totals_flag = 0; - iterator->count = 0; - iterator->size = 0; - iterator->hits = 0; - iterator->regex = NULL; + iterator->count = 0; + iterator->size = 0; + iterator->hits = 0; + iterator->regex = NULL; iterator->search_hash = NULL; if (search && Z_TYPE_P(search) == IS_STRING && Z_STRLEN_P(search)) { #ifdef ITERATOR_PCRE iterator->regex = zend_string_copy(Z_STR_P(search)); - iterator->re = pcre_get_compiled_regex(iterator->regex, NULL, NULL); + iterator->re = pcre_get_compiled_regex(iterator->regex, NULL, NULL); - if(!iterator->re) { + if (!iterator->re) { apc_error("Could not compile regular expression: %s", Z_STRVAL_P(search)); - zend_string_release(iterator->regex); + zend_string_release(iterator->regex); } #else - apc_error("Regular expressions support is not enabled, please enable PCRE for " APC_ITERATOR_NAME " regex support."); + apc_error("Regular expressions support is not enabled, please enable PCRE for " APC_ITERATOR_NAME + " regex support."); #endif } else if (search && Z_TYPE_P(search) == IS_ARRAY) { Z_ADDREF_P(search); @@ -344,25 +374,27 @@ void apc_iterator_obj_init(apc_iterator_t *iterator, zval *search, zend_long for } /* {{{ proto object APCuIterator::__construct([ mixed search [, long format [, long chunk_size [, long list ]]]]) */ -PHP_METHOD(apc_iterator, __construct) { - apc_iterator_t *iterator = apc_iterator_fetch(getThis()); - zend_long format = APC_ITER_ALL; - zend_long chunk_size=0; - zval *search = NULL; - zend_long list = APC_LIST_ACTIVE; - - if (zend_parse_parameters(ZEND_NUM_ARGS(), "|zlll", &search, &format, &chunk_size, &list) == FAILURE) { +PHP_METHOD(apc_iterator, __construct) +{ + apc_iterator_t* iterator = apc_iterator_fetch(getThis()); + zend_long format = APC_ITER_ALL; + zend_long chunk_size = 0; + zval* search = NULL; + zend_long list = APC_LIST_ACTIVE; + + if (zend_parse_parameters(ZEND_NUM_ARGS(), "|zlll", &search, &format, &chunk_size, &list) == FAILURE) { return; } - apc_iterator_obj_init(iterator, search, format, chunk_size, list); + apc_iterator_obj_init(iterator, search, format, chunk_size, list); } /* }}} */ /* {{{ proto APCuIterator::rewind() */ -PHP_METHOD(apc_iterator, rewind) { - apc_iterator_t *iterator = apc_iterator_fetch(getThis()); - +PHP_METHOD(apc_iterator, rewind) +{ + apc_iterator_t* iterator = apc_iterator_fetch(getThis()); + if (zend_parse_parameters_none() == FAILURE) { return; } @@ -371,16 +403,17 @@ PHP_METHOD(apc_iterator, rewind) { RETURN_FALSE; } - iterator->slot_idx = 0; + iterator->slot_idx = 0; iterator->stack_idx = 0; - iterator->key_idx = 0; + iterator->key_idx = 0; iterator->fetch(iterator); } /* }}} */ /* {{{ proto boolean APCuIterator::valid() */ -PHP_METHOD(apc_iterator, valid) { - apc_iterator_t *iterator = apc_iterator_fetch(getThis()); +PHP_METHOD(apc_iterator, valid) +{ + apc_iterator_t* iterator = apc_iterator_fetch(getThis()); if (zend_parse_parameters_none() == FAILURE) { return; @@ -399,9 +432,10 @@ PHP_METHOD(apc_iterator, valid) { /* }}} */ /* {{{ proto mixed APCuIterator::current() */ -PHP_METHOD(apc_iterator, current) { - apc_iterator_item_t *item; - apc_iterator_t *iterator = apc_iterator_fetch(getThis()); +PHP_METHOD(apc_iterator, current) +{ + apc_iterator_item_t* item; + apc_iterator_t* iterator = apc_iterator_fetch(getThis()); if (zend_parse_parameters_none() == FAILURE) { return; @@ -417,16 +451,16 @@ PHP_METHOD(apc_iterator, current) { } } - item = apc_stack_get - (iterator->stack, iterator->stack_idx); + item = apc_stack_get(iterator->stack, iterator->stack_idx); ZVAL_COPY(return_value, &item->value); } /* }}} */ /* {{{ proto string APCuIterator::key() */ -PHP_METHOD(apc_iterator, key) { - apc_iterator_item_t *item; - apc_iterator_t *iterator = apc_iterator_fetch(getThis()); +PHP_METHOD(apc_iterator, key) +{ + apc_iterator_item_t* item; + apc_iterator_t* iterator = apc_iterator_fetch(getThis()); if (zend_parse_parameters_none() == FAILURE) { return; @@ -453,8 +487,9 @@ PHP_METHOD(apc_iterator, key) { /* }}} */ /* {{{ proto APCuIterator::next() */ -PHP_METHOD(apc_iterator, next) { - apc_iterator_t *iterator = apc_iterator_fetch(getThis()); +PHP_METHOD(apc_iterator, next) +{ + apc_iterator_t* iterator = apc_iterator_fetch(getThis()); if (zend_parse_parameters_none() == FAILURE) { return; @@ -472,8 +507,9 @@ PHP_METHOD(apc_iterator, next) { /* }}} */ /* {{{ proto long APCuIterator::getTotalHits() */ -PHP_METHOD(apc_iterator, getTotalHits) { - apc_iterator_t *iterator = apc_iterator_fetch(getThis()); +PHP_METHOD(apc_iterator, getTotalHits) +{ + apc_iterator_t* iterator = apc_iterator_fetch(getThis()); if (zend_parse_parameters_none() == FAILURE) { return; @@ -492,8 +528,9 @@ PHP_METHOD(apc_iterator, getTotalHits) { /* }}} */ /* {{{ proto long APCuIterator::getTotalSize() */ -PHP_METHOD(apc_iterator, getTotalSize) { - apc_iterator_t *iterator = apc_iterator_fetch(getThis()); +PHP_METHOD(apc_iterator, getTotalSize) +{ + apc_iterator_t* iterator = apc_iterator_fetch(getThis()); if (zend_parse_parameters_none() == FAILURE) { return; @@ -512,8 +549,9 @@ PHP_METHOD(apc_iterator, getTotalSize) { /* }}} */ /* {{{ proto long APCuIterator::getTotalCount() */ -PHP_METHOD(apc_iterator, getTotalCount) { - apc_iterator_t *iterator = apc_iterator_fetch(getThis()); +PHP_METHOD(apc_iterator, getTotalCount) +{ + apc_iterator_t* iterator = apc_iterator_fetch(getThis()); if (zend_parse_parameters_none() == FAILURE) { return; @@ -533,10 +571,10 @@ PHP_METHOD(apc_iterator, getTotalCount) { /* {{{ arginfo */ ZEND_BEGIN_ARG_INFO_EX(arginfo_apc_iterator___construct, 0, 0, 0) - ZEND_ARG_INFO(0, search) - ZEND_ARG_INFO(0, format) - ZEND_ARG_INFO(0, chunk_size) - ZEND_ARG_INFO(0, list) +ZEND_ARG_INFO(0, search) +ZEND_ARG_INFO(0, format) +ZEND_ARG_INFO(0, chunk_size) +ZEND_ARG_INFO(0, list) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO_EX(arginfo_apc_iterator_void, 0, 0, 0) @@ -545,31 +583,32 @@ ZEND_END_ARG_INFO() /* {{{ apc_iterator_functions */ static zend_function_entry apc_iterator_functions[] = { - PHP_ME(apc_iterator, __construct, arginfo_apc_iterator___construct, ZEND_ACC_PUBLIC|ZEND_ACC_CTOR) - PHP_ME(apc_iterator, rewind, arginfo_apc_iterator_void, ZEND_ACC_PUBLIC) - PHP_ME(apc_iterator, current, arginfo_apc_iterator_void, ZEND_ACC_PUBLIC) - PHP_ME(apc_iterator, key, arginfo_apc_iterator_void, ZEND_ACC_PUBLIC) - PHP_ME(apc_iterator, next, arginfo_apc_iterator_void, ZEND_ACC_PUBLIC) - PHP_ME(apc_iterator, valid, arginfo_apc_iterator_void, ZEND_ACC_PUBLIC) - PHP_ME(apc_iterator, getTotalHits, arginfo_apc_iterator_void, ZEND_ACC_PUBLIC) - PHP_ME(apc_iterator, getTotalSize, arginfo_apc_iterator_void, ZEND_ACC_PUBLIC) - PHP_ME(apc_iterator, getTotalCount, arginfo_apc_iterator_void, ZEND_ACC_PUBLIC) - PHP_FE_END + PHP_ME(apc_iterator, __construct, arginfo_apc_iterator___construct, ZEND_ACC_PUBLIC | ZEND_ACC_CTOR) + PHP_ME(apc_iterator, rewind, arginfo_apc_iterator_void, ZEND_ACC_PUBLIC) + PHP_ME(apc_iterator, current, arginfo_apc_iterator_void, ZEND_ACC_PUBLIC) + PHP_ME(apc_iterator, key, arginfo_apc_iterator_void, ZEND_ACC_PUBLIC) + PHP_ME(apc_iterator, next, arginfo_apc_iterator_void, ZEND_ACC_PUBLIC) + PHP_ME(apc_iterator, valid, arginfo_apc_iterator_void, ZEND_ACC_PUBLIC) + PHP_ME(apc_iterator, getTotalHits, arginfo_apc_iterator_void, ZEND_ACC_PUBLIC) + PHP_ME(apc_iterator, getTotalSize, arginfo_apc_iterator_void, ZEND_ACC_PUBLIC) + PHP_ME(apc_iterator, getTotalCount, arginfo_apc_iterator_void, ZEND_ACC_PUBLIC) PHP_FE_END }; /* }}} */ /* {{{ apc_iterator_init */ -int apc_iterator_init(int module_number) { +int +apc_iterator_init(int module_number) +{ zend_class_entry ce; INIT_CLASS_ENTRY(ce, APC_ITERATOR_NAME, apc_iterator_functions); - apc_iterator_ce = zend_register_internal_class(&ce); + apc_iterator_ce = zend_register_internal_class(&ce); apc_iterator_ce->create_object = apc_iterator_create; zend_class_implements(apc_iterator_ce, 1, zend_ce_iterator); REGISTER_LONG_CONSTANT("APC_LIST_ACTIVE", APC_LIST_ACTIVE, CONST_PERSISTENT | CONST_CS); REGISTER_LONG_CONSTANT("APC_LIST_DELETED", APC_LIST_DELETED, CONST_PERSISTENT | CONST_CS); - REGISTER_LONG_CONSTANT("APC_ITER_TYPE", APC_ITER_TYPE, CONST_PERSISTENT | CONST_CS); + REGISTER_LONG_CONSTANT("APC_ITER_TYPE", APC_ITER_TYPE, CONST_PERSISTENT | CONST_CS); REGISTER_LONG_CONSTANT("APC_ITER_KEY", APC_ITER_KEY, CONST_PERSISTENT | CONST_CS); REGISTER_LONG_CONSTANT("APC_ITER_VALUE", APC_ITER_VALUE, CONST_PERSISTENT | CONST_CS); REGISTER_LONG_CONSTANT("APC_ITER_NUM_HITS", APC_ITER_NUM_HITS, CONST_PERSISTENT | CONST_CS); @@ -586,18 +625,20 @@ int apc_iterator_init(int module_number) { memcpy(&apc_iterator_object_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers)); apc_iterator_object_handlers.clone_obj = apc_iterator_clone; - apc_iterator_object_handlers.free_obj = apc_iterator_free; - apc_iterator_object_handlers.offset = XtOffsetOf(apc_iterator_t, obj); + apc_iterator_object_handlers.free_obj = apc_iterator_free; + apc_iterator_object_handlers.offset = XtOffsetOf(apc_iterator_t, obj); return SUCCESS; } /* }}} */ /* {{{ apc_iterator_delete */ -int apc_iterator_delete(zval *zobj) { - apc_iterator_t *iterator; - zend_class_entry *ce = Z_OBJCE_P(zobj); - apc_iterator_item_t *item; +int +apc_iterator_delete(zval* zobj) +{ + apc_iterator_t* iterator; + zend_class_entry* ce = Z_OBJCE_P(zobj); + apc_iterator_item_t* item; if (!ce || !instanceof_function(ce, apc_iterator_ce)) { apc_error("apc_delete object argument must be instance of " APC_ITERATOR_NAME "."); @@ -612,8 +653,7 @@ int apc_iterator_delete(zval *zobj) { while (iterator->fetch(iterator)) { while (iterator->stack_idx < apc_stack_size(iterator->stack)) { item = apc_stack_get(iterator->stack, iterator->stack_idx++); - apc_cache_delete( - apc_user_cache, item->key); + apc_cache_delete(apc_user_cache, item->key); } } @@ -621,7 +661,6 @@ int apc_iterator_delete(zval *zobj) { } /* }}} */ - /* * Local variables: * tab-width: 4 diff --git a/apc_iterator.h b/apc_iterator.h index 302e4a0a..db6c3d69 100644 --- a/apc_iterator.h +++ b/apc_iterator.h @@ -26,80 +26,75 @@ #include "apc_stack.h" #if HAVE_PCRE || HAVE_BUNDLED_PCRE -# include "ext/pcre/php_pcre.h" -# include "zend_smart_str.h" -# define ITERATOR_PCRE 1 +#include "ext/pcre/php_pcre.h" +#include "zend_smart_str.h" +#define ITERATOR_PCRE 1 #endif - #define APC_ITERATOR_NAME "APCuIterator" #define APC_DEFAULT_CHUNK_SIZE 100 -#define APC_LIST_ACTIVE 0x1 -#define APC_LIST_DELETED 0x2 +#define APC_LIST_ACTIVE 0x1 +#define APC_LIST_DELETED 0x2 -#define APC_ITER_TYPE (1 << 0) -#define APC_ITER_KEY (1 << 1) -#define APC_ITER_VALUE (1 << 2) -#define APC_ITER_NUM_HITS (1 << 3) -#define APC_ITER_MTIME (1 << 4) -#define APC_ITER_CTIME (1 << 5) -#define APC_ITER_DTIME (1 << 6) -#define APC_ITER_ATIME (1 << 7) -#define APC_ITER_REFCOUNT (1 << 8) -#define APC_ITER_MEM_SIZE (1 << 9) -#define APC_ITER_TTL (1 << 10) +#define APC_ITER_TYPE (1 << 0) +#define APC_ITER_KEY (1 << 1) +#define APC_ITER_VALUE (1 << 2) +#define APC_ITER_NUM_HITS (1 << 3) +#define APC_ITER_MTIME (1 << 4) +#define APC_ITER_CTIME (1 << 5) +#define APC_ITER_DTIME (1 << 6) +#define APC_ITER_ATIME (1 << 7) +#define APC_ITER_REFCOUNT (1 << 8) +#define APC_ITER_MEM_SIZE (1 << 9) +#define APC_ITER_TTL (1 << 10) -#define APC_ITER_NONE 0 -#define APC_ITER_ALL (0xffffffffL) +#define APC_ITER_NONE 0 +#define APC_ITER_ALL (0xffffffffL) -typedef void* (*apc_iterator_item_cb_t)(apc_cache_slot_t **slot); +typedef void* (*apc_iterator_item_cb_t)(apc_cache_slot_t** slot); /* {{{ apc_iterator_t */ typedef struct _apc_iterator_t { - short int initialized; /* sanity check in case __construct failed */ - zend_long format; /* format bitmask of the return values ie: key, value, info */ - int (*fetch)(struct _apc_iterator_t *iterator); - /* fetch callback to fetch items from cache slots or lists */ - zend_long slot_idx; /* index to the slot array or linked list */ - zend_long chunk_size; /* number of entries to pull down per fetch */ - apc_stack_t *stack; /* stack of entries pulled from cache */ - int stack_idx; /* index into the current stack */ + short int initialized; /* sanity check in case __construct failed */ + zend_long format; /* format bitmask of the return values ie: key, value, info */ + int (*fetch)(struct _apc_iterator_t* iterator); + /* fetch callback to fetch items from cache slots or lists */ + zend_long slot_idx; /* index to the slot array or linked list */ + zend_long chunk_size; /* number of entries to pull down per fetch */ + apc_stack_t* stack; /* stack of entries pulled from cache */ + int stack_idx; /* index into the current stack */ #ifdef ITERATOR_PCRE - pcre *re; /* regex filter on entry identifiers */ + pcre* re; /* regex filter on entry identifiers */ #endif - zend_string *regex; - HashTable *search_hash; /* hash of keys to iterate over */ - zend_long key_idx; /* incrementing index for numerical keys */ - short int totals_flag; /* flag if totals have been calculated */ - zend_long hits; /* hit total */ - size_t size; /* size total */ - zend_long count; /* count total */ + zend_string* regex; + HashTable* search_hash; /* hash of keys to iterate over */ + zend_long key_idx; /* incrementing index for numerical keys */ + short int totals_flag; /* flag if totals have been calculated */ + zend_long hits; /* hit total */ + size_t size; /* size total */ + zend_long count; /* count total */ zend_object obj; } apc_iterator_t; /* }}} */ -#define apc_iterator_fetch_from(o) ((apc_iterator_t*)((char*)o - XtOffsetOf(apc_iterator_t, obj))) +#define apc_iterator_fetch_from(o) ((apc_iterator_t*) ((char*) o - XtOffsetOf(apc_iterator_t, obj))) #define apc_iterator_fetch(z) apc_iterator_fetch_from(Z_OBJ_P(z)) /* {{{ apc_iterator_item */ typedef struct _apc_iterator_item_t { - zend_string *key; + zend_string* key; zval value; } apc_iterator_item_t; /* }}} */ -PHP_APCU_API void apc_iterator_obj_init( - apc_iterator_t *iterator, - zval *search, - zend_long format, - zend_long chunk_size, - zend_long list); +PHP_APCU_API void +apc_iterator_obj_init(apc_iterator_t* iterator, zval* search, zend_long format, zend_long chunk_size, zend_long list); PHP_APCU_API zend_class_entry* apc_iterator_get_ce(void); PHP_APCU_API int apc_iterator_init(int module_number); -extern int apc_iterator_delete(zval *key); +extern int apc_iterator_delete(zval* key); #endif /* diff --git a/apc_lock.c b/apc_lock.c index 80697a41..44022b0d 100644 --- a/apc_lock.c +++ b/apc_lock.c @@ -19,7 +19,7 @@ #define HAVE_APC_LOCK #ifndef HAVE_APC_LOCK_H -# include "apc_lock.h" +#include "apc_lock.h" #endif /* @@ -30,199 +30,202 @@ /* {{{ There's very little point in initializing a billion sets of attributes */ #ifndef PHP_WIN32 -# ifndef APC_SPIN_LOCK -# ifndef APC_FCNTL_LOCK -# ifdef APC_LOCK_RECURSIVE - static pthread_mutexattr_t apc_lock_attr; -# else - static pthread_rwlockattr_t apc_lock_attr; -# endif -# else -# include -# include - - static int apc_fcntl_call(int fd, int cmd, int type, off_t offset, int whence, off_t len) { - int ret; - struct flock lock; +#ifndef APC_SPIN_LOCK +#ifndef APC_FCNTL_LOCK +#ifdef APC_LOCK_RECURSIVE +static pthread_mutexattr_t apc_lock_attr; +#else +static pthread_rwlockattr_t apc_lock_attr; +#endif +#else +#include +#include + +static int +apc_fcntl_call(int fd, int cmd, int type, off_t offset, int whence, off_t len) +{ + int ret; + struct flock lock; - lock.l_type = type; - lock.l_start = offset; - lock.l_whence = whence; - lock.l_len = len; - lock.l_pid = 0; + lock.l_type = type; + lock.l_start = offset; + lock.l_whence = whence; + lock.l_len = len; + lock.l_pid = 0; - do { - ret = fcntl(fd, cmd, &lock) ; - } while(ret < 0 && errno == EINTR); - - return(ret); - } -# endif -# else -PHP_APCU_API int apc_lock_init(apc_lock_t* lock) + do { + ret = fcntl(fd, cmd, &lock); + } while (ret < 0 && errno == EINTR); + + return (ret); +} +#endif +#else +PHP_APCU_API int +apc_lock_init(apc_lock_t* lock) { lock->state = 0; } -PHP_APCU_API int apc_lock_try(apc_lock_t* lock) +PHP_APCU_API int +apc_lock_try(apc_lock_t* lock) { int failed = 1; - - asm volatile - ( - "xchgl %0, 0(%1)" : - "=r" (failed) : "r" (&lock->state), - "0" (failed) - ); - - return failed; + + asm volatile("xchgl %0, 0(%1)" : "=r"(failed) : "r"(&lock->state), "0"(failed)); + + return failed; } -PHP_APCU_API int apc_lock_get(apc_lock_t* lock) +PHP_APCU_API int +apc_lock_get(apc_lock_t* lock) { int failed = 1; - + do { - failed = apc_lock_try( - lock); + failed = apc_lock_try(lock); #ifdef APC_LOCK_NICE usleep(0); #endif } while (failed); - + return failed; } -PHP_APCU_API int apc_lock_release(apc_lock_t* lock) +PHP_APCU_API int +apc_lock_release(apc_lock_t* lock) { int released = 0; - - asm volatile ( - "xchg %0, 0(%1)" : "=r" (released) : "r" (&lock->state), - "0" (released) - ); - + + asm volatile("xchg %0, 0(%1)" : "=r"(released) : "r"(&lock->state), "0"(released)); + return !released; } -# endif +#endif static zend_bool apc_lock_ready = 0; #endif /* }}} */ /* {{{ Initialize the global lock attributes */ -PHP_APCU_API zend_bool apc_lock_init() { +PHP_APCU_API zend_bool +apc_lock_init() +{ #ifndef PHP_WIN32 - if (apc_lock_ready) - return 1; + if (apc_lock_ready) + return 1; - /* once per process please */ - apc_lock_ready = 1; + /* once per process please */ + apc_lock_ready = 1; #ifndef APC_SPIN_LOCK -# ifndef APC_FCNTL_LOCK -# ifdef APC_LOCK_RECURSIVE - if (pthread_mutexattr_init(&apc_lock_attr) == SUCCESS) { - if (pthread_mutexattr_setpshared(&apc_lock_attr, PTHREAD_PROCESS_SHARED) == SUCCESS) { - pthread_mutexattr_settype(&apc_lock_attr, PTHREAD_MUTEX_RECURSIVE); - return 1; - } - } -# else - if (pthread_rwlockattr_init(&apc_lock_attr) == SUCCESS) { - if (pthread_rwlockattr_setpshared(&apc_lock_attr, PTHREAD_PROCESS_SHARED) == SUCCESS) { - return 1; - } - } -# endif -# endif -#endif - return 0; +#ifndef APC_FCNTL_LOCK +#ifdef APC_LOCK_RECURSIVE + if (pthread_mutexattr_init(&apc_lock_attr) == SUCCESS) { + if (pthread_mutexattr_setpshared(&apc_lock_attr, PTHREAD_PROCESS_SHARED) == SUCCESS) { + pthread_mutexattr_settype(&apc_lock_attr, PTHREAD_MUTEX_RECURSIVE); + return 1; + } + } #else - return 1; + if (pthread_rwlockattr_init(&apc_lock_attr) == SUCCESS) { + if (pthread_rwlockattr_setpshared(&apc_lock_attr, PTHREAD_PROCESS_SHARED) == SUCCESS) { + return 1; + } + } +#endif +#endif +#endif + return 0; +#else + return 1; #endif } /* }}} */ /* {{{ Cleanup attributes and statics */ -PHP_APCU_API void apc_lock_cleanup() { +PHP_APCU_API void +apc_lock_cleanup() +{ #ifndef PHP_WIN32 - if (!apc_lock_ready) - return; + if (!apc_lock_ready) + return; - /* once per process please */ - apc_lock_ready = 0; + /* once per process please */ + apc_lock_ready = 0; #ifndef APC_SPIN_LOCK -# ifndef APC_FCNTL_LOCK -# ifdef APC_LOCK_RECURSIVE - pthread_mutexattr_destroy(&apc_lock_attr); -# else - pthread_rwlockattr_destroy(&apc_lock_attr); -# endif -# endif +#ifndef APC_FCNTL_LOCK +#ifdef APC_LOCK_RECURSIVE + pthread_mutexattr_destroy(&apc_lock_attr); +#else + pthread_rwlockattr_destroy(&apc_lock_attr); +#endif +#endif #endif #endif } /* }}} */ -PHP_APCU_API zend_bool apc_lock_create(apc_lock_t *lock) { +PHP_APCU_API zend_bool +apc_lock_create(apc_lock_t* lock) +{ #ifndef PHP_WIN32 -# ifndef APC_SPIN_LOCK -# ifndef APC_FCNTL_LOCK -# ifdef APC_LOCK_RECURSIVE - { - pthread_mutex_init(lock, &apc_lock_attr); - return 1; - } -# else - { - /* Native */ - return (pthread_rwlock_init(lock, &apc_lock_attr)==SUCCESS); - } -# endif -# else +#ifndef APC_SPIN_LOCK +#ifndef APC_FCNTL_LOCK +#ifdef APC_LOCK_RECURSIVE + { + pthread_mutex_init(lock, &apc_lock_attr); + return 1; + } +#else + { + /* Native */ + return (pthread_rwlock_init(lock, &apc_lock_attr) == SUCCESS); + } +#endif +#else { /* FCNTL */ char lock_path[] = "/tmp/.apc.XXXXXX"; - mktemp( - lock_path); - (*lock) = open(lock_path, O_RDWR|O_CREAT, 0666); - if((*lock) > 0 ) { - unlink( - lock_path); + mktemp(lock_path); + (*lock) = open(lock_path, O_RDWR | O_CREAT, 0666); + if ((*lock) > 0) { + unlink(lock_path); return 1; } else { return 0; } } -# endif +#endif #else { /* SPIN */ lock->state = 0; return 1; } - + #endif #else - lock = (apc_lock_t *)apc_windows_cs_create((apc_windows_cs_rwlock_t *)lock); + lock = (apc_lock_t*) apc_windows_cs_create((apc_windows_cs_rwlock_t*) lock); - return (NULL != lock); + return (NULL != lock); #endif } -PHP_APCU_API zend_bool apc_lock_rlock(apc_lock_t *lock) { +PHP_APCU_API zend_bool +apc_lock_rlock(apc_lock_t* lock) +{ #ifndef PHP_WIN32 #ifndef APC_SPIN_LOCK -# ifndef APC_FCNTL_LOCK -# ifdef APC_LOCK_RECURSIVE - pthread_mutex_lock(lock); -# else - pthread_rwlock_rdlock(lock); -# endif -# else +#ifndef APC_FCNTL_LOCK +#ifdef APC_LOCK_RECURSIVE + pthread_mutex_lock(lock); +#else + pthread_rwlock_rdlock(lock); +#endif +#else { /* FCNTL */ apc_fcntl_call((*lock), F_SETLKW, F_RDLCK, 0, SEEK_SET, 0); } -# endif +#endif #else { /* SPIN */ @@ -230,26 +233,28 @@ PHP_APCU_API zend_bool apc_lock_rlock(apc_lock_t *lock) { } #endif #else - apc_windows_cs_rdlock((apc_windows_cs_rwlock_t *)lock); + apc_windows_cs_rdlock((apc_windows_cs_rwlock_t*) lock); #endif - return 1; + return 1; } -PHP_APCU_API zend_bool apc_lock_wlock(apc_lock_t *lock) { +PHP_APCU_API zend_bool +apc_lock_wlock(apc_lock_t* lock) +{ #ifndef PHP_WIN32 #ifndef APC_SPIN_LOCK -# ifndef APC_FCNTL_LOCK -# ifdef APC_LOCK_RECURSIVE - pthread_mutex_lock(lock); -# else - pthread_rwlock_wrlock(lock); -# endif -# else +#ifndef APC_FCNTL_LOCK +#ifdef APC_LOCK_RECURSIVE + pthread_mutex_lock(lock); +#else + pthread_rwlock_wrlock(lock); +#endif +#else { /* FCNTL */ apc_fcntl_call((*lock), F_SETLKW, F_WRLCK, 0, SEEK_SET, 0); } -# endif +#endif #else { /* SPIN */ @@ -257,26 +262,28 @@ PHP_APCU_API zend_bool apc_lock_wlock(apc_lock_t *lock) { } #endif #else - apc_windows_cs_lock((apc_windows_cs_rwlock_t *)lock); + apc_windows_cs_lock((apc_windows_cs_rwlock_t*) lock); #endif - return 1; + return 1; } -PHP_APCU_API zend_bool apc_lock_wunlock(apc_lock_t *lock) { +PHP_APCU_API zend_bool +apc_lock_wunlock(apc_lock_t* lock) +{ #ifndef PHP_WIN32 #ifndef APC_SPIN_LOCK -# ifndef APC_FCNTL_LOCK -# ifdef APC_LOCK_RECURSIVE - pthread_mutex_unlock(lock); -# else - pthread_rwlock_unlock(lock); -# endif -# else +#ifndef APC_FCNTL_LOCK +#ifdef APC_LOCK_RECURSIVE + pthread_mutex_unlock(lock); +#else + pthread_rwlock_unlock(lock); +#endif +#else { /* FCNTL */ apc_fcntl_call((*lock), F_SETLKW, F_UNLCK, 0, SEEK_SET, 0); } -# endif +#endif #else { /* SPIN */ @@ -284,26 +291,28 @@ PHP_APCU_API zend_bool apc_lock_wunlock(apc_lock_t *lock) { } #endif #else - apc_windows_cs_unlock_wr((apc_windows_cs_rwlock_t *)lock); + apc_windows_cs_unlock_wr((apc_windows_cs_rwlock_t*) lock); #endif - return 1; + return 1; } -PHP_APCU_API zend_bool apc_lock_runlock(apc_lock_t *lock) { +PHP_APCU_API zend_bool +apc_lock_runlock(apc_lock_t* lock) +{ #ifndef PHP_WIN32 #ifndef APC_SPIN_LOCK -# ifndef APC_FCNTL_LOCK -# ifdef APC_LOCK_RECURSIVE - pthread_mutex_unlock(lock); -# else - pthread_rwlock_unlock(lock); -# endif -# else +#ifndef APC_FCNTL_LOCK +#ifdef APC_LOCK_RECURSIVE + pthread_mutex_unlock(lock); +#else + pthread_rwlock_unlock(lock); +#endif +#else { /* FCNTL */ apc_fcntl_call((*lock), F_SETLKW, F_UNLCK, 0, SEEK_SET, 0); } -# endif +#endif #else { /* SPIN */ @@ -311,30 +320,31 @@ PHP_APCU_API zend_bool apc_lock_runlock(apc_lock_t *lock) { } #endif #else - apc_windows_cs_unlock_rd((apc_windows_cs_rwlock_t *)lock); + apc_windows_cs_unlock_rd((apc_windows_cs_rwlock_t*) lock); #endif - return 1; + return 1; } -PHP_APCU_API void apc_lock_destroy(apc_lock_t *lock) { +PHP_APCU_API void +apc_lock_destroy(apc_lock_t* lock) +{ #ifndef PHP_WIN32 #ifndef APC_SPIN_LOCK -# ifndef APC_FCNTL_LOCK -# ifdef APC_LOCK_RECURSIVE - /* nothing */ -# else - /* nothing */ -# endif -# else +#ifndef APC_FCNTL_LOCK +#ifdef APC_LOCK_RECURSIVE +/* nothing */ +#else +/* nothing */ +#endif +#else { /* FCNTL */ - close ((*lock)); + close((*lock)); } -# endif +#endif #endif #else - apc_windows_cs_destroy((apc_windows_cs_rwlock_t *)lock); + apc_windows_cs_destroy((apc_windows_cs_rwlock_t*) lock); #endif -} +} #endif - diff --git a/apc_lock.h b/apc_lock.h index a7c7799f..133c6f43 100644 --- a/apc_lock.h +++ b/apc_lock.h @@ -20,13 +20,13 @@ #define APC_LOCK_H #ifdef HAVE_CONFIG_H -# include +#include #endif #include "apc.h" #ifndef APC_LOCK_API_H -# include "apc_lock_api.h" +#include "apc_lock_api.h" #endif #endif diff --git a/apc_lock_api.h b/apc_lock_api.h index 2a6e7793..74b5dbcd 100644 --- a/apc_lock_api.h +++ b/apc_lock_api.h @@ -22,32 +22,32 @@ /* APCu works most efficiently where there is access to native read/write locks If the current system has native rwlocks present they will be used, if they are - not present, APCu will emulate their behavior with standard mutex. + not present, APCu will emulate their behavior with standard mutex. While APCu is emulating read/write locks, reads and writes are exclusive, - additionally the write lock prefers readers, as is the default behaviour of - the majority of Posix rwlock implementations + additionally the write lock prefers readers, as is the default behaviour of + the majority of Posix rwlock implementations */ #ifndef PHP_WIN32 -# ifndef __USE_UNIX98 -# define __USE_UNIX98 -# endif -# include "pthread.h" -# ifndef APC_SPIN_LOCK -# ifndef APC_FCNTL_LOCK -# if defined(APC_NATIVE_RWLOCK) && defined(HAVE_ATOMIC_OPERATIONS) - typedef pthread_rwlock_t apc_lock_t; -# define APC_LOCK_SHARED -# else - typedef pthread_mutex_t apc_lock_t; -# define APC_LOCK_RECURSIVE -# endif -# else - typedef int apc_lock_t; -# define APC_LOCK_FILE -# endif -# else -# define APC_LOCK_NICE 1 +#ifndef __USE_UNIX98 +#define __USE_UNIX98 +#endif +#include "pthread.h" +#ifndef APC_SPIN_LOCK +#ifndef APC_FCNTL_LOCK +#if defined(APC_NATIVE_RWLOCK) && defined(HAVE_ATOMIC_OPERATIONS) +typedef pthread_rwlock_t apc_lock_t; +#define APC_LOCK_SHARED +#else +typedef pthread_mutex_t apc_lock_t; +#define APC_LOCK_RECURSIVE +#endif +#else +typedef int apc_lock_t; +#define APC_LOCK_FILE +#endif +#else +#define APC_LOCK_NICE 1 typedef struct { unsigned long state; } apc_lock_t; @@ -56,82 +56,100 @@ PHP_APCU_API int apc_lock_init(apc_lock_t* lock); PHP_APCU_API int apc_lock_try(apc_lock_t* lock); PHP_APCU_API int apc_lock_get(apc_lock_t* lock); PHP_APCU_API int apc_lock_release(apc_lock_t* lock); -# endif +#endif #else /* XXX kernel lock mode only for now, compatible through all the wins, add more ifdefs for others */ -# include "apc_windows_srwlock_kernel.h" +#include "apc_windows_srwlock_kernel.h" typedef apc_windows_cs_rwlock_t apc_lock_t; -# define APC_LOCK_SHARED +#define APC_LOCK_SHARED #endif /* {{{ functions */ /* The following functions should be called once per process: - apc_lock_init initializes attributes suitable for all locks - apc_lock_cleanup destroys those attributes + apc_lock_init initializes attributes suitable for all locks + apc_lock_cleanup destroys those attributes This saves us from having to create and destroy attributes for every lock we use at runtime */ PHP_APCU_API zend_bool apc_lock_init(); -PHP_APCU_API void apc_lock_cleanup(); +PHP_APCU_API void apc_lock_cleanup(); /* The following functions should be self explanitory: */ -PHP_APCU_API zend_bool apc_lock_create(apc_lock_t *lock); -PHP_APCU_API zend_bool apc_lock_rlock(apc_lock_t *lock); -PHP_APCU_API zend_bool apc_lock_wlock(apc_lock_t *lock); -PHP_APCU_API zend_bool apc_lock_runlock(apc_lock_t *lock); -PHP_APCU_API zend_bool apc_lock_wunlock(apc_lock_t *lock); -PHP_APCU_API void apc_lock_destroy(apc_lock_t *lock); /* }}} */ +PHP_APCU_API zend_bool apc_lock_create(apc_lock_t* lock); +PHP_APCU_API zend_bool apc_lock_rlock(apc_lock_t* lock); +PHP_APCU_API zend_bool apc_lock_wlock(apc_lock_t* lock); +PHP_APCU_API zend_bool apc_lock_runlock(apc_lock_t* lock); +PHP_APCU_API zend_bool apc_lock_wunlock(apc_lock_t* lock); +PHP_APCU_API void apc_lock_destroy(apc_lock_t* lock); /* }}} */ /* {{{ generic locking macros */ -#define CREATE_LOCK(lock) apc_lock_create(lock) -#define DESTROY_LOCK(lock) apc_lock_destroy(lock) -#define WLOCK(lock) { HANDLE_BLOCK_INTERRUPTIONS(); apc_lock_wlock(lock); } -#define WUNLOCK(lock) { apc_lock_wunlock(lock); HANDLE_UNBLOCK_INTERRUPTIONS(); } -#define RLOCK(lock) { HANDLE_BLOCK_INTERRUPTIONS(); apc_lock_rlock(lock); } -#define RUNLOCK(lock) { apc_lock_runlock(lock); HANDLE_UNBLOCK_INTERRUPTIONS(); } -#define LOCK WLOCK -#define UNLOCK WUNLOCK +#define CREATE_LOCK(lock) apc_lock_create(lock) +#define DESTROY_LOCK(lock) apc_lock_destroy(lock) +#define WLOCK(lock) \ + { \ + HANDLE_BLOCK_INTERRUPTIONS(); \ + apc_lock_wlock(lock); \ + } +#define WUNLOCK(lock) \ + { \ + apc_lock_wunlock(lock); \ + HANDLE_UNBLOCK_INTERRUPTIONS(); \ + } +#define RLOCK(lock) \ + { \ + HANDLE_BLOCK_INTERRUPTIONS(); \ + apc_lock_rlock(lock); \ + } +#define RUNLOCK(lock) \ + { \ + apc_lock_runlock(lock); \ + HANDLE_UNBLOCK_INTERRUPTIONS(); \ + } +#define LOCK WLOCK +#define UNLOCK WUNLOCK /* }}} */ /* {{{ object locking macros */ -#define APC_WLOCK(o) WLOCK(&(o)->lock) -#define APC_LOCK APC_WLOCK -#define APC_WUNLOCK(o) WUNLOCK(&(o)->lock) -#define APC_UNLOCK APC_WUNLOCK -#define APC_RLOCK(o) RLOCK(&(o)->lock) -#define APC_RUNLOCK(o) RUNLOCK(&(o)->lock) /* }}} */ +#define APC_WLOCK(o) WLOCK(&(o)->lock) +#define APC_LOCK APC_WLOCK +#define APC_WUNLOCK(o) WUNLOCK(&(o)->lock) +#define APC_UNLOCK APC_WUNLOCK +#define APC_RLOCK(o) RLOCK(&(o)->lock) +#define APC_RUNLOCK(o) RUNLOCK(&(o)->lock) /* }}} */ /* atomic operations */ #if defined(APC_LOCK_SHARED) -# ifdef PHP_WIN32 -# ifdef _WIN64 -# define ATOMIC_INC(c, a) InterlockedIncrement64(&a) -# define ATOMIC_DEC(c, a) InterlockedDecrement64(&a) -# else -# define ATOMIC_INC(c, a) InterlockedIncrement(&a) -# define ATOMIC_DEC(c, a) InterlockedDecrement(&a) -# endif -# else -# define ATOMIC_INC(c, a) __sync_add_and_fetch(&a, 1) -# define ATOMIC_DEC(c, a) __sync_sub_and_fetch(&a, 1) -# endif +#ifdef PHP_WIN32 +#ifdef _WIN64 +#define ATOMIC_INC(c, a) InterlockedIncrement64(&a) +#define ATOMIC_DEC(c, a) InterlockedDecrement64(&a) +#else +#define ATOMIC_INC(c, a) InterlockedIncrement(&a) +#define ATOMIC_DEC(c, a) InterlockedDecrement(&a) +#endif +#else +#define ATOMIC_INC(c, a) __sync_add_and_fetch(&a, 1) +#define ATOMIC_DEC(c, a) __sync_sub_and_fetch(&a, 1) +#endif #elif defined(APC_LOCK_RECURSIVE) -# define ATOMIC_INC(c, a) do { \ - if (apc_lock_wlock(&(c)->header->lock)) { \ - (a)++; \ - apc_lock_wunlock(&(c)->header->lock); \ - } \ -} while(0) -# define ATOMIC_DEC(c, a) do { \ - if (apc_lock_wlock(&(c)->header->lock)) { \ - (a)--; \ - apc_lock_wunlock(&(c)->header->lock); \ - } \ -} while(0) +#define ATOMIC_INC(c, a) \ + do { \ + if (apc_lock_wlock(&(c)->header->lock)) { \ + (a)++; \ + apc_lock_wunlock(&(c)->header->lock); \ + } \ + } while (0) +#define ATOMIC_DEC(c, a) \ + do { \ + if (apc_lock_wlock(&(c)->header->lock)) { \ + (a)--; \ + apc_lock_wunlock(&(c)->header->lock); \ + } \ + } while (0) #else -# define ATOMIC_INC(c, a) (a)++ -# define ATOMIC_DEC(c, a) (a)-- +#define ATOMIC_INC(c, a) (a)++ +#define ATOMIC_DEC(c, a) (a)-- #endif #endif diff --git a/apc_mmap.c b/apc_mmap.c index 53491afd..25037366 100644 --- a/apc_mmap.c +++ b/apc_mmap.c @@ -50,40 +50,43 @@ /* support for systems where MAP_ANONYMOUS is defined but not MAP_ANON, ie: HP-UX bug #14615 */ #if !defined(MAP_ANON) && defined(MAP_ANONYMOUS) -# define MAP_ANON MAP_ANONYMOUS +#define MAP_ANON MAP_ANONYMOUS #endif -apc_segment_t apc_mmap(char *file_mask, size_t size) +apc_segment_t +apc_mmap(char* file_mask, size_t size) { - apc_segment_t segment; + apc_segment_t segment; - int fd = -1; + int fd = -1; int flags = MAP_SHARED | MAP_NOSYNC; #ifdef APC_MEMPROTECT int remap = 1; #endif /* If no filename was provided, do an anonymous mmap */ - if(!file_mask || (file_mask && !strlen(file_mask))) { + if (!file_mask || (file_mask && !strlen(file_mask))) { #if !defined(MAP_ANON) - apc_error("Anonymous mmap does not apear to be available on this system (MAP_ANON/MAP_ANONYMOUS). Please see the apc.mmap_file_mask INI option."); + apc_error( + "Anonymous mmap does not apear to be available on this system (MAP_ANON/MAP_ANONYMOUS). Please see the " + "apc.mmap_file_mask INI option."); #else - fd = -1; + fd = -1; flags = MAP_SHARED | MAP_ANON; #ifdef APC_MEMPROTECT remap = 0; #endif #endif - } else if(!strcmp(file_mask,"/dev/zero")) { + } else if (!strcmp(file_mask, "/dev/zero")) { fd = open("/dev/zero", O_RDWR, S_IRUSR | S_IWUSR); - if(fd == -1) { + if (fd == -1) { apc_error("apc_mmap: open on /dev/zero failed:"); goto error; } #ifdef APC_MEMPROTECT remap = 0; /* cannot remap */ #endif - } else if(strstr(file_mask,".shm")) { + } else if (strstr(file_mask, ".shm")) { /* * If the filemask contains .shm we try to do a POSIX-compliant shared memory * backed mmap which should avoid synchs on some platforms. At least on @@ -94,12 +97,12 @@ apc_segment_t apc_mmap(char *file_mask, size_t size) * On FreeBSD these are mapped onto the regular filesystem so you can put whatever * path you want here. */ - if(!mktemp(file_mask)) { + if (!mktemp(file_mask)) { apc_error("apc_mmap: mktemp on %s failed:", file_mask); goto error; } - fd = shm_open(file_mask, O_CREAT|O_RDWR, S_IRUSR|S_IWUSR); - if(fd == -1) { + fd = shm_open(file_mask, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR); + if (fd == -1) { apc_error("apc_mmap: shm_open on %s failed:", file_mask); goto error; } @@ -115,7 +118,7 @@ apc_segment_t apc_mmap(char *file_mask, size_t size) * Otherwise we do a normal filesystem mmap */ fd = mkstemp(file_mask); - if(fd == -1) { + if (fd == -1) { apc_error("apc_mmap: mkstemp on %s failed:", file_mask); goto error; } @@ -128,36 +131,38 @@ apc_segment_t apc_mmap(char *file_mask, size_t size) unlink(file_mask); } - segment.shmaddr = (void *)mmap(NULL, size, PROT_READ | PROT_WRITE, flags, fd, 0); - segment.size = size; + segment.shmaddr = (void*) mmap(NULL, size, PROT_READ | PROT_WRITE, flags, fd, 0); + segment.size = size; #ifdef APC_MEMPROTECT - if(remap) { - segment.roaddr = (void *)mmap(NULL, size, PROT_READ, flags, fd, 0); + if (remap) { + segment.roaddr = (void*) mmap(NULL, size, PROT_READ, flags, fd, 0); } else { segment.roaddr = NULL; } #endif - if((long)segment.shmaddr == -1) { + if ((long) segment.shmaddr == -1) { apc_error("apc_mmap: mmap failed:"); } - if(fd != -1) close(fd); - + if (fd != -1) + close(fd); + return segment; error: - segment.shmaddr = (void*)-1; - segment.size = 0; + segment.shmaddr = (void*) -1; + segment.size = 0; #ifdef APC_MEMPROTECT segment.roaddr = NULL; #endif return segment; } -void apc_unmap(apc_segment_t *segment) +void +apc_unmap(apc_segment_t* segment) { if (munmap(segment->shmaddr, segment->size) < 0) { apc_warning("apc_unmap: munmap failed:"); @@ -168,7 +173,6 @@ void apc_unmap(apc_segment_t *segment) apc_warning("apc_unmap: munmap failed:"); } #endif - } #endif diff --git a/apc_mmap.h b/apc_mmap.h index 7be5c0ca..683ff2e4 100644 --- a/apc_mmap.h +++ b/apc_mmap.h @@ -38,7 +38,7 @@ /* Wrapper functions for shared memory mapped files */ #if APC_MMAP -apc_segment_t apc_mmap(char *file_mask, size_t size); +apc_segment_t apc_mmap(char* file_mask, size_t size); void apc_unmap(apc_segment_t* segment); #endif diff --git a/apc_pool.c b/apc_pool.c index 05c89c0b..659f32d7 100644 --- a/apc_pool.c +++ b/apc_pool.c @@ -27,14 +27,13 @@ /* $Id: apc_pool.c 327069 2012-08-12 08:56:55Z laruence $ */ - #include "apc_pool.h" #include #ifdef APC_POOL_DEBUG -# ifdef HAVE_VALGRIND_MEMCHECK_H -# include -# endif +#ifdef HAVE_VALGRIND_MEMCHECK_H +#include +#endif #endif /* {{{ forward references */ @@ -43,24 +42,26 @@ static apc_pool* apc_realpool_create(apc_pool_type type, apc_malloc_t, apc_free_ /* }}} */ /* {{{ apc_pool_create */ -PHP_APCU_API apc_pool* apc_pool_create(apc_pool_type pool_type, - apc_malloc_t allocate, - apc_free_t deallocate, - apc_protect_t protect, - apc_unprotect_t unprotect) +PHP_APCU_API apc_pool* +apc_pool_create(apc_pool_type pool_type, + apc_malloc_t allocate, + apc_free_t deallocate, + apc_protect_t protect, + apc_unprotect_t unprotect) { - if(pool_type == APC_UNPOOL) { + if (pool_type == APC_UNPOOL) { return apc_unpool_create(pool_type, allocate, deallocate, protect, unprotect); } - return apc_realpool_create(pool_type, allocate, deallocate, protect, unprotect); + return apc_realpool_create(pool_type, allocate, deallocate, protect, unprotect); } /* }}} */ /* {{{ apc_pool_destroy */ -PHP_APCU_API void apc_pool_destroy(apc_pool *pool) +PHP_APCU_API void +apc_pool_destroy(apc_pool* pool) { - apc_free_t deallocate = pool->deallocate; + apc_free_t deallocate = pool->deallocate; apc_pcleanup_t cleanup = pool->cleanup; cleanup(pool); @@ -77,10 +78,10 @@ struct _apc_unpool { /* apc_unpool is a lie! */ }; -static void* apc_unpool_alloc(apc_pool* pool, - size_t size) +static void* +apc_unpool_alloc(apc_pool* pool, size_t size) { - apc_unpool *upool = (apc_unpool*)pool; + apc_unpool* upool = (apc_unpool*) pool; apc_malloc_t allocate = upool->parent.allocate; @@ -90,25 +91,24 @@ static void* apc_unpool_alloc(apc_pool* pool, return allocate(size); } -static void apc_unpool_free(apc_pool* pool, - void *ptr) +static void +apc_unpool_free(apc_pool* pool, void* ptr) { - apc_unpool *upool = (apc_unpool*) pool; + apc_unpool* upool = (apc_unpool*) pool; apc_free_t deallocate = upool->parent.deallocate; deallocate(ptr); } -static void apc_unpool_cleanup(apc_pool* pool) +static void +apc_unpool_cleanup(apc_pool* pool) { } -static apc_pool* apc_unpool_create(apc_pool_type type, - apc_malloc_t allocate, - apc_free_t deallocate, - apc_protect_t protect, - apc_unprotect_t unprotect) +static apc_pool* +apc_unpool_create( + apc_pool_type type, apc_malloc_t allocate, apc_free_t deallocate, apc_protect_t protect, apc_unprotect_t unprotect) { apc_unpool* upool = allocate(sizeof(apc_unpool)); @@ -116,11 +116,11 @@ static apc_pool* apc_unpool_create(apc_pool_type type, return NULL; } - upool->parent.type = type; - upool->parent.allocate = allocate; + upool->parent.type = type; + upool->parent.allocate = allocate; upool->parent.deallocate = deallocate; - upool->parent.protect = protect; + upool->parent.protect = protect; upool->parent.unprotect = unprotect; upool->parent.palloc = apc_unpool_alloc; @@ -138,15 +138,14 @@ static apc_pool* apc_unpool_create(apc_pool_type type, /*{{{ apc_realpool implementation */ /* {{{ typedefs */ -typedef struct _pool_block -{ - size_t avail; - size_t capacity; - unsigned char *mark; - struct _pool_block *next; - unsigned :0; /* this should align to word */ +typedef struct _pool_block { + size_t avail; + size_t capacity; + unsigned char* mark; + struct _pool_block* next; + unsigned : 0; /* this should align to word */ /* data comes here */ -}pool_block; +} pool_block; /* parts in ? are optional and turned on for fun, memory loss, @@ -161,55 +160,52 @@ typedef struct _pool_block typedef struct _apc_realpool apc_realpool; -struct _apc_realpool -{ +struct _apc_realpool { struct _apc_pool parent; - size_t dsize; - void *owner; + size_t dsize; + void* owner; unsigned long count; - pool_block *head; - pool_block first; + pool_block* head; + pool_block first; }; /* }}} */ /* {{{ redzone code */ -static const unsigned char decaff[] = { - 0xde, 0xca, 0xff, 0xc0, 0xff, 0xee, 0xba, 0xad, - 0xde, 0xca, 0xff, 0xc0, 0xff, 0xee, 0xba, 0xad, - 0xde, 0xca, 0xff, 0xc0, 0xff, 0xee, 0xba, 0xad, - 0xde, 0xca, 0xff, 0xc0, 0xff, 0xee, 0xba, 0xad -}; +static const unsigned char decaff[] = { 0xde, 0xca, 0xff, 0xc0, 0xff, 0xee, 0xba, 0xad, 0xde, 0xca, 0xff, + 0xc0, 0xff, 0xee, 0xba, 0xad, 0xde, 0xca, 0xff, 0xc0, 0xff, 0xee, + 0xba, 0xad, 0xde, 0xca, 0xff, 0xc0, 0xff, 0xee, 0xba, 0xad }; /* a redzone is at least 4 (0xde,0xca,0xc0,0xff) bytes */ -#define REDZONE_SIZE(size) \ - ((ALIGNWORD((size)) > ((size) + 4)) ? \ - (ALIGNWORD((size)) - (size)) : /* does not change realsize */\ - ALIGNWORD((size)) - (size) + ALIGNWORD((sizeof(char)))) /* adds 1 word to realsize */ +#define REDZONE_SIZE(size) \ + ((ALIGNWORD((size)) > ((size) + 4)) ? (ALIGNWORD((size)) - (size)) : /* does not change realsize */ \ + ALIGNWORD((size)) - (size) + ALIGNWORD((sizeof(char)))) /* adds 1 word to realsize */ #define SIZEINFO_SIZE ALIGNWORD(sizeof(size_t)) -#define MARK_REDZONE(block, redsize) do {\ - memcpy(block, decaff, redsize );\ - } while(0) +#define MARK_REDZONE(block, redsize) \ + do { \ + memcpy(block, decaff, redsize); \ + } while (0) #define CHECK_REDZONE(block, redsize) (memcmp(block, decaff, redsize) == 0) /* }}} */ -#define INIT_POOL_BLOCK(rpool, entry, size) do {\ - (entry)->avail = (entry)->capacity = (size);\ - (entry)->mark = ((unsigned char*)(entry)) + ALIGNWORD(sizeof(pool_block));\ - (entry)->next = (rpool)->head;\ - (rpool)->head = (entry);\ -} while(0) +#define INIT_POOL_BLOCK(rpool, entry, size) \ + do { \ + (entry)->avail = (entry)->capacity = (size); \ + (entry)->mark = ((unsigned char*) (entry)) + ALIGNWORD(sizeof(pool_block)); \ + (entry)->next = (rpool)->head; \ + (rpool)->head = (entry); \ + } while (0) /* {{{ create_pool_block */ -static pool_block* create_pool_block(apc_realpool *rpool, - size_t size) +static pool_block* +create_pool_block(apc_realpool* rpool, size_t size) { apc_malloc_t allocate = rpool->parent.allocate; @@ -222,7 +218,7 @@ static pool_block* create_pool_block(apc_realpool *rpool, } INIT_POOL_BLOCK(rpool, entry, size); - + rpool->parent.size += realsize; rpool->count++; @@ -232,42 +228,42 @@ static pool_block* create_pool_block(apc_realpool *rpool, /* }}} */ /* {{{ apc_realpool_alloc */ -static void* apc_realpool_alloc(apc_pool *pool, - size_t size) +static void* +apc_realpool_alloc(apc_pool* pool, size_t size) { - apc_realpool *rpool = (apc_realpool*)pool; - unsigned char *p = NULL; - size_t realsize = ALIGNWORD(size); + apc_realpool* rpool = (apc_realpool*) pool; + unsigned char* p = NULL; + size_t realsize = ALIGNWORD(size); size_t poolsize; - unsigned char *redzone = NULL; - size_t redsize = 0; - size_t *sizeinfo= NULL; - pool_block *entry = NULL; + unsigned char* redzone = NULL; + size_t redsize = 0; + size_t* sizeinfo = NULL; + pool_block* entry = NULL; unsigned long i; - - if(APC_POOL_HAS_REDZONES(pool)) { - redsize = REDZONE_SIZE(size); /* redsize might be re-using word size padding */ - realsize = size + redsize; /* recalculating realsize */ + + if (APC_POOL_HAS_REDZONES(pool)) { + redsize = REDZONE_SIZE(size); /* redsize might be re-using word size padding */ + realsize = size + redsize; /* recalculating realsize */ } else { redsize = realsize - size; /* use padding space */ } - if(APC_POOL_HAS_SIZEINFO(pool)) { + if (APC_POOL_HAS_SIZEINFO(pool)) { realsize += ALIGNWORD(sizeof(size_t)); } /* minimize look-back, a value of 8 seems to give similar fill-ratios (+2%) * as looping through the entire list. And much faster in allocations. */ - for(entry = rpool->head, i = 0; entry != NULL && (i < 8); entry = entry->next, i++) { - if(entry->avail >= realsize) { + for (entry = rpool->head, i = 0; entry != NULL && (i < 8); entry = entry->next, i++) { + if (entry->avail >= realsize) { goto found; } } /* upgrade the pool type to reduce overhead */ - if(rpool->count > 4 && rpool->dsize < 4096) { + if (rpool->count > 4 && rpool->dsize < 4096) { rpool->dsize = 4096; - } else if(rpool->count > 8 && rpool->dsize < 8192) { + } else if (rpool->count > 8 && rpool->dsize < 8192) { rpool->dsize = 8192; } @@ -275,41 +271,41 @@ static void* apc_realpool_alloc(apc_pool *pool, entry = create_pool_block(rpool, poolsize); - if(!entry) { + if (!entry) { return NULL; } found: p = entry->mark; - if(APC_POOL_HAS_SIZEINFO(pool)) { - sizeinfo = (size_t*)p; + if (APC_POOL_HAS_SIZEINFO(pool)) { + sizeinfo = (size_t*) p; p += SIZEINFO_SIZE; *sizeinfo = size; } redzone = p + size; - if(APC_POOL_HAS_REDZONES(pool)) { + if (APC_POOL_HAS_REDZONES(pool)) { MARK_REDZONE(redzone, redsize); } #ifdef VALGRIND_MAKE_MEM_NOACCESS - if(redsize != 0) { + if (redsize != 0) { VALGRIND_MAKE_MEM_NOACCESS(redzone, redsize); } #endif entry->avail -= realsize; - entry->mark += realsize; - pool->used += realsize; + entry->mark += realsize; + pool->used += realsize; #ifdef VALGRIND_MAKE_MEM_UNDEFINED /* need to write before reading data off this */ VALGRIND_MAKE_MEM_UNDEFINED(p, size); #endif - return (void*)p; + return (void*) p; } /* }}} */ @@ -323,34 +319,34 @@ static void* apc_realpool_alloc(apc_pool *pool, * is accessible from gdb, eventhough it is never * used in code in non-debug builds. */ -static APC_USED int apc_realpool_check_integrity(apc_realpool *rpool) +static APC_USED int +apc_realpool_check_integrity(apc_realpool* rpool) { - apc_pool *pool = &(rpool->parent); - pool_block *entry; - size_t *sizeinfo = NULL; - unsigned char *start; + apc_pool* pool = &(rpool->parent); + pool_block* entry; + size_t* sizeinfo = NULL; + unsigned char* start; size_t realsize; - unsigned char *redzone; + unsigned char* redzone; size_t redsize; - for(entry = rpool->head; entry != NULL; entry = entry->next) { - start = (unsigned char *)entry + ALIGNWORD(sizeof(pool_block)); - if((entry->mark - start) != (entry->capacity - entry->avail)) { + for (entry = rpool->head; entry != NULL; entry = entry->next) { + start = (unsigned char*) entry + ALIGNWORD(sizeof(pool_block)); + if ((entry->mark - start) != (entry->capacity - entry->avail)) { return 0; } } - if(!APC_POOL_HAS_REDZONES(pool) || - !APC_POOL_HAS_SIZEINFO(pool)) { - (void)pool; /* remove unused warning */ + if (!APC_POOL_HAS_REDZONES(pool) || !APC_POOL_HAS_SIZEINFO(pool)) { + (void) pool; /* remove unused warning */ return 1; } - for(entry = rpool->head; entry != NULL; entry = entry->next) { - start = (unsigned char *)entry + ALIGNWORD(sizeof(pool_block)); + for (entry = rpool->head; entry != NULL; entry = entry->next) { + start = (unsigned char*) entry + ALIGNWORD(sizeof(pool_block)); - while(start < entry->mark) { - sizeinfo = (size_t*)start; + while (start < entry->mark) { + sizeinfo = (size_t*) start; /* redzone starts where real data ends, in a non-word boundary * redsize is at least 4 bytes + whatever's needed to make it * to another word boundary. @@ -360,10 +356,9 @@ static APC_USED int apc_realpool_check_integrity(apc_realpool *rpool) #ifdef VALGRIND_MAKE_MEM_DEFINED VALGRIND_MAKE_MEM_DEFINED(redzone, redsize); #endif - if(!CHECK_REDZONE(redzone, redsize)) - { + if (!CHECK_REDZONE(redzone, redsize)) { /* - fprintf(stderr, "Redzone check failed for %p\n", + fprintf(stderr, "Redzone check failed for %p\n", start + ALIGNWORD(sizeof(size_t)));*/ return 0; } @@ -383,25 +378,26 @@ static APC_USED int apc_realpool_check_integrity(apc_realpool *rpool) /* * free does not do anything */ -static void apc_realpool_free(apc_pool *pool, - void *p) +static void +apc_realpool_free(apc_pool* pool, void* p) { } /* }}} */ /* {{{ apc_realpool_cleanup */ -static void apc_realpool_cleanup(apc_pool *pool) +static void +apc_realpool_cleanup(apc_pool* pool) { - pool_block *entry; - pool_block *tmp; - apc_realpool *rpool = (apc_realpool*)pool; + pool_block* entry; + pool_block* tmp; + apc_realpool* rpool = (apc_realpool*) pool; apc_free_t deallocate = pool->deallocate; - assert(apc_realpool_check_integrity(rpool)!=0); + assert(apc_realpool_check_integrity(rpool) != 0); entry = rpool->head; - while(entry->next != NULL) { + while (entry->next != NULL) { tmp = entry->next; deallocate(entry); entry = tmp; @@ -410,42 +406,40 @@ static void apc_realpool_cleanup(apc_pool *pool) /* }}} */ /* {{{ apc_realpool_create */ -static apc_pool* apc_realpool_create(apc_pool_type type, - apc_malloc_t allocate, - apc_free_t deallocate, - apc_protect_t protect, - apc_unprotect_t unprotect) +static apc_pool* +apc_realpool_create( + apc_pool_type type, apc_malloc_t allocate, apc_free_t deallocate, apc_protect_t protect, apc_unprotect_t unprotect) { size_t dsize = 0; - apc_realpool *rpool; + apc_realpool* rpool; - switch(type & APC_POOL_SIZE_MASK) { - case APC_SMALL_POOL: - dsize = 512; - break; + switch (type & APC_POOL_SIZE_MASK) { + case APC_SMALL_POOL: + dsize = 512; + break; - case APC_LARGE_POOL: - dsize = 8192; - break; + case APC_LARGE_POOL: + dsize = 8192; + break; - case APC_MEDIUM_POOL: - dsize = 4096; - break; + case APC_MEDIUM_POOL: + dsize = 4096; + break; - default: - return NULL; + default: + return NULL; } - rpool = (apc_realpool*)allocate((sizeof(apc_realpool) + ALIGNWORD(dsize))); + rpool = (apc_realpool*) allocate((sizeof(apc_realpool) + ALIGNWORD(dsize))); - if(!rpool) { + if (!rpool) { return NULL; } rpool->parent.type = type; - rpool->parent.allocate = allocate; + rpool->parent.allocate = allocate; rpool->parent.deallocate = deallocate; rpool->parent.size = sizeof(apc_realpool) + ALIGNWORD(dsize); @@ -453,13 +447,13 @@ static apc_pool* apc_realpool_create(apc_pool_type type, rpool->parent.palloc = apc_realpool_alloc; rpool->parent.pfree = apc_realpool_free; - rpool->parent.protect = protect; + rpool->parent.protect = protect; rpool->parent.unprotect = unprotect; rpool->parent.cleanup = apc_realpool_cleanup; rpool->dsize = dsize; - rpool->head = NULL; + rpool->head = NULL; rpool->count = 0; INIT_POOL_BLOCK(rpool, &(rpool->first), dsize); @@ -467,13 +461,13 @@ static apc_pool* apc_realpool_create(apc_pool_type type, return &(rpool->parent); } - /* }}} */ /* }}} */ /* {{{ apc_pool_init */ -PHP_APCU_API void apc_pool_init() +PHP_APCU_API void +apc_pool_init() { /* put all ye sanity checks here */ assert(sizeof(decaff) > REDZONE_SIZE(ALIGNWORD(sizeof(char)))); @@ -485,17 +479,16 @@ PHP_APCU_API void apc_pool_init() /* }}} */ /* {{{ apc_pstrdup */ -PHP_APCU_API void* APC_ALLOC apc_pstrdup(const char* s, - apc_pool* pool) +PHP_APCU_API void* APC_ALLOC +apc_pstrdup(const char* s, apc_pool* pool) { return s != NULL ? apc_pmemcpy(s, (strlen(s) + 1), pool) : NULL; } /* }}} */ /* {{{ apc_pmemcpy */ -PHP_APCU_API void* APC_ALLOC apc_pmemcpy(const void* p, - size_t n, - apc_pool* pool) +PHP_APCU_API void* APC_ALLOC +apc_pmemcpy(const void* p, size_t n, apc_pool* pool) { void* q; @@ -508,49 +501,51 @@ PHP_APCU_API void* APC_ALLOC apc_pmemcpy(const void* p, /* }}} */ /* {{{ apc_pstrcpy */ -PHP_APCU_API zend_string* apc_pstrcpy(zend_string *str, apc_pool* pool) { - zend_string* p = (zend_string*) pool->palloc(pool, - ZEND_MM_ALIGNED_SIZE(_ZSTR_STRUCT_SIZE(ZSTR_LEN(str)))); - - if (!p) { - return NULL; - } - - memset(p, 0, sizeof(zend_string)); - - GC_REFCOUNT(p) = 1; - /* shouldn't be important, except for debugging */ - GC_TYPE_INFO(p) = IS_STRING; - - memcpy(ZSTR_VAL(p), ZSTR_VAL(str), ZSTR_LEN(str)); - p->len = ZSTR_LEN(str); - ZSTR_VAL(p)[ZSTR_LEN(p)] = '\0'; - zend_string_forget_hash_val(p); - - return p; +PHP_APCU_API zend_string* +apc_pstrcpy(zend_string* str, apc_pool* pool) +{ + zend_string* p = (zend_string*) pool->palloc(pool, ZEND_MM_ALIGNED_SIZE(_ZSTR_STRUCT_SIZE(ZSTR_LEN(str)))); + + if (!p) { + return NULL; + } + + memset(p, 0, sizeof(zend_string)); + + GC_REFCOUNT(p) = 1; + /* shouldn't be important, except for debugging */ + GC_TYPE_INFO(p) = IS_STRING; + + memcpy(ZSTR_VAL(p), ZSTR_VAL(str), ZSTR_LEN(str)); + p->len = ZSTR_LEN(str); + ZSTR_VAL(p)[ZSTR_LEN(p)] = '\0'; + zend_string_forget_hash_val(p); + + return p; } /* }}} */ /* {{{ apc_pstrnew */ -PHP_APCU_API zend_string* apc_pstrnew(unsigned char *buf, size_t buf_len, apc_pool* pool) { - zend_string* p = (zend_string*) pool->palloc(pool, - ZEND_MM_ALIGNED_SIZE(_ZSTR_STRUCT_SIZE(buf_len))); - - if (!p) { - return NULL; - } - - memset(p, 0, sizeof(zend_string)); - - GC_REFCOUNT(p) = 1; - /* shouldn't be important, except for debugging */ - GC_TYPE_INFO(p) = IS_STRING; - - memcpy(ZSTR_VAL(p), buf, buf_len); - p->len = buf_len; - ZSTR_VAL(p)[ZSTR_LEN(p)] = '\0'; - zend_string_forget_hash_val(p); - - return p; +PHP_APCU_API zend_string* +apc_pstrnew(unsigned char* buf, size_t buf_len, apc_pool* pool) +{ + zend_string* p = (zend_string*) pool->palloc(pool, ZEND_MM_ALIGNED_SIZE(_ZSTR_STRUCT_SIZE(buf_len))); + + if (!p) { + return NULL; + } + + memset(p, 0, sizeof(zend_string)); + + GC_REFCOUNT(p) = 1; + /* shouldn't be important, except for debugging */ + GC_TYPE_INFO(p) = IS_STRING; + + memcpy(ZSTR_VAL(p), buf, buf_len); + p->len = buf_len; + ZSTR_VAL(p)[ZSTR_LEN(p)] = '\0'; + zend_string_forget_hash_val(p); + + return p; } /* }}} */ /* diff --git a/apc_pool.h b/apc_pool.h index ddf382ef..ee31d1a3 100644 --- a/apc_pool.h +++ b/apc_pool.h @@ -33,7 +33,7 @@ #include "apc_sma.h" #ifndef APC_POOL_API_H -# include "apc_pool_api.h" +#include "apc_pool_api.h" #endif /* @@ -41,4 +41,3 @@ */ extern PHP_APCU_API void apc_pool_init(); #endif - diff --git a/apc_pool_api.h b/apc_pool_api.h index 81afea9d..a86ec89f 100644 --- a/apc_pool_api.h +++ b/apc_pool_api.h @@ -31,8 +31,8 @@ #define APC_POOL_API_H #if APC_POOL_DEBUG -#define APC_POOL_HAS_SIZEINFO(pool) ((pool->type & APC_POOL_SIZEINFO)!=0) -#define APC_POOL_HAS_REDZONES(pool) ((pool->type & APC_POOL_REDZONES)!=0) +#define APC_POOL_HAS_SIZEINFO(pool) ((pool->type & APC_POOL_SIZEINFO) != 0) +#define APC_POOL_HAS_REDZONES(pool) ((pool->type & APC_POOL_REDZONES) != 0) #else /* let gcc optimize away the optional features */ #define APC_POOL_HAS_SIZEINFO(pool) (0) @@ -43,11 +43,11 @@ typedef struct _apc_pool apc_pool; /* }}} */ /* {{{ functions */ -typedef void (*apc_pcleanup_t)(apc_pool *pool); -typedef void* (*apc_palloc_t)(apc_pool *pool, size_t size); -typedef void (*apc_pfree_t) (apc_pool *pool, void* p); -typedef void* (*apc_protect_t) (void *p); -typedef void* (*apc_unprotect_t)(void *p); /* }}} */ +typedef void (*apc_pcleanup_t)(apc_pool* pool); +typedef void* (*apc_palloc_t)(apc_pool* pool, size_t size); +typedef void (*apc_pfree_t)(apc_pool* pool, void* p); +typedef void* (*apc_protect_t)(void* p); +typedef void* (*apc_unprotect_t)(void* p); /* }}} */ /* {{{ enum definition: apc_pool_type */ typedef enum { @@ -55,67 +55,62 @@ typedef enum { APC_SMALL_POOL = 0x1, APC_MEDIUM_POOL = 0x2, APC_LARGE_POOL = 0x3, - APC_POOL_SIZE_MASK = 0x7, /* waste a bit */ + APC_POOL_SIZE_MASK = 0x7, /* waste a bit */ #if APC_POOL_DEBUG - APC_POOL_REDZONES = 0x08, - APC_POOL_SIZEINFO = 0x10, - APC_POOL_OPT_MASK = 0x18 + APC_POOL_REDZONES = 0x08, + APC_POOL_SIZEINFO = 0x10, + APC_POOL_OPT_MASK = 0x18 #endif } apc_pool_type; /* }}} */ -/* {{{ structure definition: apc_pool */ +/* {{{ structure definition: apc_pool */ struct _apc_pool { - /* denotes the size and debug flags for a pool */ - apc_pool_type type; - - /* handler functions */ - apc_malloc_t allocate; - apc_free_t deallocate; + /* denotes the size and debug flags for a pool */ + apc_pool_type type; - apc_palloc_t palloc; - apc_pfree_t pfree; + /* handler functions */ + apc_malloc_t allocate; + apc_free_t deallocate; - apc_protect_t protect; - apc_unprotect_t unprotect; + apc_palloc_t palloc; + apc_pfree_t pfree; - apc_pcleanup_t cleanup; + apc_protect_t protect; + apc_unprotect_t unprotect; - /* total */ - size_t size; - /* remaining */ - size_t used; + apc_pcleanup_t cleanup; + + /* total */ + size_t size; + /* remaining */ + size_t used; /* apc_realpool and apc_unpool add more here */ }; /* }}} */ /* {{{ enum definition: apc_copy_type */ -/* APC_COPY_IN should be used when copying into APC +/* APC_COPY_IN should be used when copying into APC APC_COPY_OUT should be used when copying out of APC */ -typedef enum _apc_copy_type { - APC_NO_COPY = 0, - APC_COPY_IN, - APC_COPY_OUT, - APC_COPY_OTHER -} apc_copy_type; /* }}} */ - -/* {{{ enum definition: apc_context_type - APC_CONTEXT_SHARE should be used to create contexts using shared memory - APC_CONTEXT_NOSHARE should be used to create contexts using standard allocators */ +typedef enum _apc_copy_type { APC_NO_COPY = 0, APC_COPY_IN, APC_COPY_OUT, APC_COPY_OTHER } apc_copy_type; /* }}} */ + +/* {{{ enum definition: apc_context_type + APC_CONTEXT_SHARE should be used to create contexts using shared memory + APC_CONTEXT_NOSHARE should be used to create contexts using standard allocators */ typedef enum _apc_context_type { - APC_CONTEXT_NONE = 0, + APC_CONTEXT_NONE = 0, APC_CONTEXT_SHARE, - APC_CONTEXT_NOSHARE + APC_CONTEXT_NOSHARE } apc_context_type; /* }}} */ /* {{{ struct definition: apc_context_t */ typedef struct _apc_context_t { - apc_pool* pool; /* pool of memory for context */ - apc_copy_type copy; /* copying type for context */ - unsigned int force_update:1; /* flag to force updates */ - HashTable copied; /* copied zvals for recursion support */ - apc_serializer_t* serializer; /* serializer */ - void* key; /* set before serializer API is invoked */ -} apc_context_t; /* }}} */ + apc_pool* pool; /* pool of memory for context */ + apc_copy_type copy; /* copying type for context */ + unsigned int force_update : 1; /* flag to force updates */ + HashTable copied; /* copied zvals for recursion support */ + apc_serializer_t* serializer; /* serializer */ + void* key; /* set before serializer API is invoked */ +} apc_context_t; /* }}} */ /* apc_pool_create creates a pool of the specified type, setting the handlers passed on the pool, returns apc_pool* @@ -134,19 +129,14 @@ PHP_APCU_API void apc_pool_destroy(apc_pool* pool); /* apc_pmemcpy performs memcpy using resources provided by pool */ -PHP_APCU_API void* apc_pmemcpy(const void* p, - size_t n, - apc_pool* pool); +PHP_APCU_API void* apc_pmemcpy(const void* p, size_t n, apc_pool* pool); - -PHP_APCU_API zend_string* apc_pstrcpy(zend_string *str, apc_pool* pool); -PHP_APCU_API zend_string* apc_pstrnew(unsigned char *buf, size_t buf_len, apc_pool* pool); +PHP_APCU_API zend_string* apc_pstrcpy(zend_string* str, apc_pool* pool); +PHP_APCU_API zend_string* apc_pstrnew(unsigned char* buf, size_t buf_len, apc_pool* pool); /* apc_pstrdup performs strdup using resources provided by pool */ -PHP_APCU_API void* apc_pstrdup(const char* s, - apc_pool* pool); +PHP_APCU_API void* apc_pstrdup(const char* s, apc_pool* pool); #endif - diff --git a/apc_serializer.h b/apc_serializer.h index e7db5871..0ba72c1a 100644 --- a/apc_serializer.h +++ b/apc_serializer.h @@ -33,9 +33,9 @@ typedef int (*apc_serialize_t)(APC_SERIALIZER_ARGS); typedef int (*apc_unserialize_t)(APC_UNSERIALIZER_ARGS); typedef int (*apc_register_serializer_t)(const char* name, - apc_serialize_t serialize, - apc_unserialize_t unserialize, - void *config); + apc_serialize_t serialize, + apc_unserialize_t unserialize, + void* config); /* * ABI version for constant hooks. Increment this any time you make any changes @@ -45,33 +45,30 @@ typedef int (*apc_register_serializer_t)(const char* name, #define APC_SERIALIZER_CONSTANT "\000apc_register_serializer-" APC_SERIALIZER_ABI #if !defined(APC_UNUSED) -# if defined(__GNUC__) -# define APC_UNUSED __attribute__((unused)) -# else -# define APC_UNUSED -# endif +#if defined(__GNUC__) +#define APC_UNUSED __attribute__((unused)) +#else +#define APC_UNUSED +#endif #endif -static APC_UNUSED int apc_register_serializer(const char* name, - apc_serialize_t serialize, - apc_unserialize_t unserialize, - void *config) +static APC_UNUSED int +apc_register_serializer(const char* name, apc_serialize_t serialize, apc_unserialize_t unserialize, void* config) { int retval = 0; - zend_string *lookup = zend_string_init( - APC_SERIALIZER_CONSTANT, sizeof(APC_SERIALIZER_CONSTANT)-1, 0); - zval *magic = zend_get_constant(lookup); + zend_string* lookup = zend_string_init(APC_SERIALIZER_CONSTANT, sizeof(APC_SERIALIZER_CONSTANT) - 1, 0); + zval* magic = zend_get_constant(lookup); /* zend_get_constant will return 1 on success, otherwise apc_magic_constant wouldn't be touched at all */ if (magic) { apc_register_serializer_t register_func = (apc_register_serializer_t)(Z_LVAL_P(magic)); - if(register_func) { + if (register_func) { retval = register_func(name, serialize, unserialize, NULL); } } - zend_string_release(lookup); + zend_string_release(lookup); return retval; } diff --git a/apc_shm.c b/apc_shm.c index 8538b04b..b6cb1629 100644 --- a/apc_shm.c +++ b/apc_shm.c @@ -41,33 +41,39 @@ #endif #ifndef SHM_R -# define SHM_R 0444 /* read permission */ +#define SHM_R 0444 /* read permission */ #endif #ifndef SHM_A -# define SHM_A 0222 /* write permission */ +#define SHM_A 0222 /* write permission */ #endif -int apc_shm_create(int proj, size_t size) +int +apc_shm_create(int proj, size_t size) { - int shmid; /* shared memory id */ - int oflag; /* permissions on shm */ - key_t key = IPC_PRIVATE; /* shm key */ + int shmid; /* shared memory id */ + int oflag; /* permissions on shm */ + key_t key = IPC_PRIVATE; /* shm key */ oflag = IPC_CREAT | SHM_R | SHM_A; if ((shmid = shmget(key, size, oflag)) < 0) { - apc_error("apc_shm_create: shmget(%d, %d, %d) failed: %s. It is possible that the chosen SHM segment size is higher than the operation system allows. Linux has usually a default limit of 32MB per segment.", key, size, oflag, strerror(errno)); + apc_error( + "apc_shm_create: shmget(%d, %d, %d) failed: %s. It is possible that the chosen SHM segment size is higher " + "than the operation system allows. Linux has usually a default limit of 32MB per segment.", + key, size, oflag, strerror(errno)); } return shmid; } -void apc_shm_destroy(int shmid) +void +apc_shm_destroy(int shmid) { /* we expect this call to fail often, so we do not check */ shmctl(shmid, IPC_RMID, 0); } -apc_segment_t apc_shm_attach(int shmid, size_t size) +apc_segment_t +apc_shm_attach(int shmid, size_t size) { apc_segment_t segment; /* shm segment */ @@ -76,7 +82,7 @@ apc_segment_t apc_shm_attach(int shmid, size_t size) } #ifdef APC_MEMPROTECT - + if ((zend_long)(segment.roaddr = shmat(shmid, 0, SHM_RDONLY)) == -1) { segment.roaddr = NULL; } @@ -93,7 +99,8 @@ apc_segment_t apc_shm_attach(int shmid, size_t size) return segment; } -void apc_shm_detach(apc_segment_t* segment) +void +apc_shm_detach(apc_segment_t* segment) { if (shmdt(segment->shmaddr) < 0) { apc_error("apc_shm_detach: shmdt failed:"); diff --git a/apc_signal.c b/apc_signal.c index a7481e51..679b75b7 100644 --- a/apc_signal.c +++ b/apc_signal.c @@ -24,15 +24,15 @@ All other licensing and usage conditions are those of the PHP Group. */ - /* $Id: apc_signal.c 327066 2012-08-12 07:48:48Z laruence $ */ - - /* Allows apc to install signal handlers and maintain signalling - to already registered handlers. Registers all signals that - coredump by default and unmaps the shared memory segment - before the coredump. Note: PHP module init is called before - signals are set by Apache and thus apc_set_signals should - be called in request init (RINIT) - */ +/* $Id: apc_signal.c 327066 2012-08-12 07:48:48Z laruence $ */ + +/* Allows apc to install signal handlers and maintain signalling + to already registered handlers. Registers all signals that + coredump by default and unmaps the shared memory segment + before the coredump. Note: PHP module init is called before + signals are set by Apache and thus apc_set_signals should + be called in request init (RINIT) + */ #include "apc.h" @@ -42,24 +42,25 @@ #include "apc_sma.h" #include "apc_signal.h" -static apc_signal_info_t apc_signal_info = {0}; +static apc_signal_info_t apc_signal_info = { 0 }; static int apc_register_signal(int signo, void (*handler)(int, siginfo_t*, void*)); -static void apc_rehandle_signal(int signo, siginfo_t *siginfo, void *context); -static void apc_core_unmap(int signo, siginfo_t *siginfo, void *context); +static void apc_rehandle_signal(int signo, siginfo_t* siginfo, void* context); +static void apc_core_unmap(int signo, siginfo_t* siginfo, void* context); #if defined(SIGUSR1) && defined(APC_SIGNAL_CLEAR) -static void apc_clear_cache(int signo, siginfo_t *siginfo, void *context); +static void apc_clear_cache(int signo, siginfo_t* siginfo, void* context); #endif extern apc_cache_t* apc_user_cache; -/* {{{ apc_core_unmap - * Coredump signal handler, unmaps shm and calls previously installed handlers +/* {{{ apc_core_unmap + * Coredump signal handler, unmaps shm and calls previously installed handlers */ -static void apc_core_unmap(int signo, siginfo_t *siginfo, void *context) +static void +apc_core_unmap(int signo, siginfo_t* siginfo, void* context) { TSRMLS_FETCH(); - + apc_sma_cleanup(); apc_rehandle_signal(signo, siginfo, context); @@ -70,19 +71,19 @@ static void apc_core_unmap(int signo, siginfo_t *siginfo, void *context) #endif } /* }}} */ - #if defined(SIGUSR1) && defined(APC_SIGNAL_CLEAR) /* {{{ apc_reload_cache */ -static void apc_clear_cache(int signo, siginfo_t *siginfo, void *context) { - TSRMLS_FETCH(); - - if (apc_user_cache) { - apc_cache_clear( - apc_user_cache); - } - - apc_rehandle_signal(signo, siginfo, context); - +static void +apc_clear_cache(int signo, siginfo_t* siginfo, void* context) +{ + TSRMLS_FETCH(); + + if (apc_user_cache) { + apc_cache_clear(apc_user_cache); + } + + apc_rehandle_signal(signo, siginfo, context); + #if !defined(WIN32) && !defined(NETWARE) kill(getpid(), signo); #else @@ -94,18 +95,19 @@ static void apc_clear_cache(int signo, siginfo_t *siginfo, void *context) { /* {{{ apc_rehandle_signal * Call the previously registered handler for a signal */ -static void apc_rehandle_signal(int signo, siginfo_t *siginfo, void *context) +static void +apc_rehandle_signal(int signo, siginfo_t* siginfo, void* context) { int i; - apc_signal_entry_t p_sig = {0}; + apc_signal_entry_t p_sig = { 0 }; - for (i=0; (i < apc_signal_info.installed && p_sig.signo != signo); i++) { + for (i = 0; (i < apc_signal_info.installed && p_sig.signo != signo); i++) { p_sig = *apc_signal_info.prev[i]; if (p_sig.signo == signo) { if (p_sig.siginfo) { - (*(void (*)(int, siginfo_t*, void*))p_sig.handler)(signo, siginfo, context); + (*(void (*)(int, siginfo_t*, void*)) p_sig.handler)(signo, siginfo, context); } else { - (*(void (*)(int))p_sig.handler)(signo); + (*(void (*)(int)) p_sig.handler)(signo); } } } @@ -113,26 +115,29 @@ static void apc_rehandle_signal(int signo, siginfo_t *siginfo, void *context) } /* }}} */ /* {{{ apc_register_signal - * Set a handler for a previously installed signal and save so we can - * callback when handled + * Set a handler for a previously installed signal and save so we can + * callback when handled */ -static int apc_register_signal(int signo, void (*handler)(int, siginfo_t*, void*)) +static int +apc_register_signal(int signo, void (*handler)(int, siginfo_t*, void*)) { - struct sigaction sa = {{0}}; - apc_signal_entry_t p_sig = {0}; + struct sigaction sa = { { 0 } }; + apc_signal_entry_t p_sig = { 0 }; if (sigaction(signo, NULL, &sa) == 0) { - if ((void*)sa.sa_handler == (void*)handler) { + if ((void*) sa.sa_handler == (void*) handler) { return SUCCESS; } if (sa.sa_handler != SIG_ERR && sa.sa_handler != SIG_DFL && sa.sa_handler != SIG_IGN) { - p_sig.signo = signo; + p_sig.signo = signo; p_sig.siginfo = ((sa.sa_flags & SA_SIGINFO) == SA_SIGINFO); - p_sig.handler = (void *)sa.sa_handler; + p_sig.handler = (void*) sa.sa_handler; - apc_signal_info.prev = (apc_signal_entry_t **)apc_erealloc(apc_signal_info.prev, (apc_signal_info.installed+1)*sizeof(apc_signal_entry_t *)); - apc_signal_info.prev[apc_signal_info.installed] = (apc_signal_entry_t *)apc_emalloc(sizeof(apc_signal_entry_t)); + apc_signal_info.prev = (apc_signal_entry_t**) apc_erealloc( + apc_signal_info.prev, (apc_signal_info.installed + 1) * sizeof(apc_signal_entry_t*)); + apc_signal_info.prev[apc_signal_info.installed] = + (apc_signal_entry_t*) apc_emalloc(sizeof(apc_signal_entry_t)); *apc_signal_info.prev[apc_signal_info.installed++] = p_sig; } else { /* inherit flags and mask if already set */ @@ -145,7 +150,7 @@ static int apc_register_signal(int signo, void (*handler)(int, siginfo_t*, void* sa.sa_flags = SA_RESETHAND; #endif } - sa.sa_handler = (void*)handler; + sa.sa_handler = (void*) handler; if (sigaction(signo, &sa, NULL) < 0) { apc_warning("Error installing apc signal handler for %d", signo); @@ -158,66 +163,68 @@ static int apc_register_signal(int signo, void (*handler)(int, siginfo_t*, void* /* {{{ apc_set_signals * Install our signal handlers */ -void apc_set_signals() +void +apc_set_signals() { - if (apc_signal_info.installed == 0) { + if (apc_signal_info.installed == 0) { #if defined(SIGUSR1) && defined(APC_SIGNAL_CLEAR) - apc_register_signal(SIGUSR1, apc_clear_cache); + apc_register_signal(SIGUSR1, apc_clear_cache); #endif - if (APCG(coredump_unmap)) { - /* ISO C standard signals that coredump */ - apc_register_signal(SIGSEGV, apc_core_unmap); - apc_register_signal(SIGABRT, apc_core_unmap); - apc_register_signal(SIGFPE, apc_core_unmap); - apc_register_signal(SIGILL, apc_core_unmap); + if (APCG(coredump_unmap)) { + /* ISO C standard signals that coredump */ + apc_register_signal(SIGSEGV, apc_core_unmap); + apc_register_signal(SIGABRT, apc_core_unmap); + apc_register_signal(SIGFPE, apc_core_unmap); + apc_register_signal(SIGILL, apc_core_unmap); /* extended signals that coredump */ #ifdef SIGBUS - apc_register_signal(SIGBUS, apc_core_unmap); + apc_register_signal(SIGBUS, apc_core_unmap); #endif #ifdef SIGABORT - apc_register_signal(SIGABORT, apc_core_unmap); + apc_register_signal(SIGABORT, apc_core_unmap); #endif #ifdef SIGEMT - apc_register_signal(SIGEMT, apc_core_unmap); + apc_register_signal(SIGEMT, apc_core_unmap); #endif #ifdef SIGIOT - apc_register_signal(SIGIOT, apc_core_unmap); + apc_register_signal(SIGIOT, apc_core_unmap); #endif #ifdef SIGQUIT - apc_register_signal(SIGQUIT, apc_core_unmap); + apc_register_signal(SIGQUIT, apc_core_unmap); #endif #ifdef SIGSYS - apc_register_signal(SIGSYS, apc_core_unmap); + apc_register_signal(SIGSYS, apc_core_unmap); #endif #ifdef SIGTRAP - apc_register_signal(SIGTRAP, apc_core_unmap); + apc_register_signal(SIGTRAP, apc_core_unmap); #endif #ifdef SIGXCPU - apc_register_signal(SIGXCPU, apc_core_unmap); + apc_register_signal(SIGXCPU, apc_core_unmap); #endif #ifdef SIGXFSZ - apc_register_signal(SIGXFSZ, apc_core_unmap); + apc_register_signal(SIGXFSZ, apc_core_unmap); #endif - } - } + } + } } /* }}} */ /* {{{ apc_set_signals * cleanup signals for shutdown */ -void apc_shutdown_signals() +void +apc_shutdown_signals() { - int i=0; + int i = 0; if (apc_signal_info.installed > 0) { - for (i=0; (i < apc_signal_info.installed); i++) { + for (i = 0; (i < apc_signal_info.installed); i++) { apc_efree(apc_signal_info.prev[i]); } apc_efree(apc_signal_info.prev); apc_signal_info.installed = 0; /* just in case */ - } + } } /* }}} */ -#endif /* HAVE_SIGACTION */ +#endif /* HAVE_SIGACTION */ /* * Local variables: diff --git a/apc_signal.h b/apc_signal.h index b62e8925..a2bcd7c0 100644 --- a/apc_signal.h +++ b/apc_signal.h @@ -26,14 +26,14 @@ #include "apc_php.h" typedef struct apc_signal_entry_t { - int signo; /* signal number */ - int siginfo; /* siginfo style handler calling */ - void* handler; /* signal handler */ + int signo; /* signal number */ + int siginfo; /* siginfo style handler calling */ + void* handler; /* signal handler */ } apc_signal_entry_t; typedef struct apc_signal_info_t { - int installed; /* How many signals we've installed handles for */ - apc_signal_entry_t **prev; /* Previous signal handlers */ + int installed; /* How many signals we've installed handles for */ + apc_signal_entry_t** prev; /* Previous signal handlers */ } apc_signal_info_t; void apc_set_signals(); diff --git a/apc_sma.c b/apc_sma.c index 91ce857a..ecd79499 100644 --- a/apc_sma.c +++ b/apc_sma.c @@ -39,27 +39,25 @@ #include "apc_mmap.h" #ifdef APC_SMA_DEBUG -# ifdef HAVE_VALGRIND_MEMCHECK_H -# include -# endif -# define APC_SMA_CANARIES 1 +#ifdef HAVE_VALGRIND_MEMCHECK_H +#include +#endif +#define APC_SMA_CANARIES 1 #endif -enum { - DEFAULT_NUMSEG=1, - DEFAULT_SEGSIZE=30*1024*1024 }; +enum { DEFAULT_NUMSEG = 1, DEFAULT_SEGSIZE = 30 * 1024 * 1024 }; typedef struct sma_header_t sma_header_t; struct sma_header_t { - apc_lock_t sma_lock; /* segment lock */ - size_t segsize; /* size of entire segment */ - size_t avail; /* bytes available (not necessarily contiguous) */ + apc_lock_t sma_lock; /* segment lock */ + size_t segsize; /* size of entire segment */ + size_t avail; /* bytes available (not necessarily contiguous) */ }; -#define SMA_HDR(sma, i) ((sma_header_t*)((sma->segs[i]).shmaddr)) -#define SMA_ADDR(sma, i) ((char*)(SMA_HDR(sma, i))) -#define SMA_RO(sma, i) ((char*)(sma->segs[i]).roaddr) -#define SMA_LCK(sma, i) ((SMA_HDR(sma, i))->sma_lock) +#define SMA_HDR(sma, i) ((sma_header_t*) ((sma->segs[i]).shmaddr)) +#define SMA_ADDR(sma, i) ((char*) (SMA_HDR(sma, i))) +#define SMA_RO(sma, i) ((char*) (sma->segs[i]).roaddr) +#define SMA_LCK(sma, i) ((SMA_HDR(sma, i))->sma_lock) #if 0 /* global counter for identifying blocks @@ -71,12 +69,12 @@ static volatile size_t block_id = 0; typedef struct block_t block_t; struct block_t { - size_t size; /* size of this block */ - size_t prev_size; /* size of sequentially previous block, 0 if prev is allocated */ - size_t fnext; /* offset in segment of next free block */ - size_t fprev; /* offset in segment of prev free block */ + size_t size; /* size of this block */ + size_t prev_size; /* size of sequentially previous block, 0 if prev is allocated */ + size_t fnext; /* offset in segment of next free block */ + size_t fprev; /* offset in segment of prev free block */ #ifdef APC_SMA_CANARIES - size_t canary; /* canary to check for memory overwrites */ + size_t canary; /* canary to check for memory overwrites */ #endif #if 0 size_t id; /* identifier for the memory block */ @@ -87,22 +85,22 @@ struct block_t { * module. Both assume the presence of a variable shmaddr that points to the * beginning of the shared memory segment in question. */ -#define BLOCKAT(offset) ((block_t*)((char *)shmaddr + offset)) -#define OFFSET(block) ((size_t)(((char*)block) - (char*)shmaddr)) +#define BLOCKAT(offset) ((block_t*) ((char*) shmaddr + offset)) +#define OFFSET(block) ((size_t)(((char*) block) - (char*) shmaddr)) /* macros for getting the next or previous sequential block */ -#define NEXT_SBLOCK(block) ((block_t*)((char*)block + block->size)) -#define PREV_SBLOCK(block) (block->prev_size ? ((block_t*)((char*)block - block->prev_size)) : NULL) +#define NEXT_SBLOCK(block) ((block_t*) ((char*) block + block->size)) +#define PREV_SBLOCK(block) (block->prev_size ? ((block_t*) ((char*) block - block->prev_size)) : NULL) /* Canary macros for setting, checking and resetting memory canaries */ #ifdef APC_SMA_CANARIES - #define SET_CANARY(v) (v)->canary = 0x42424242 - #define CHECK_CANARY(v) assert((v)->canary == 0x42424242) - #define RESET_CANARY(v) (v)->canary = -42 +#define SET_CANARY(v) (v)->canary = 0x42424242 +#define CHECK_CANARY(v) assert((v)->canary == 0x42424242) +#define RESET_CANARY(v) (v)->canary = -42 #else - #define SET_CANARY(v) - #define CHECK_CANARY(v) - #define RESET_CANARY(v) +#define SET_CANARY(v) +#define CHECK_CANARY(v) +#define RESET_CANARY(v) #endif /* {{{ MINBLOCKSIZE */ @@ -110,13 +108,14 @@ struct block_t { /* }}} */ /* {{{ sma_allocate: tries to allocate at least size bytes in a segment */ -static APC_HOTSPOT size_t sma_allocate(sma_header_t* header, zend_ulong size, zend_ulong fragment, zend_ulong *allocated) +static APC_HOTSPOT size_t +sma_allocate(sma_header_t* header, zend_ulong size, zend_ulong fragment, zend_ulong* allocated) { - void* shmaddr; /* header of shared memory segment */ - block_t* prv; /* block prior to working block */ - block_t* cur; /* working block in list */ - block_t* prvnextfit; /* block before next fit */ - size_t realsize; /* actual size of block needed, including header */ + void* shmaddr; /* header of shared memory segment */ + block_t* prv; /* block prior to working block */ + block_t* cur; /* working block in list */ + block_t* prvnextfit; /* block before next fit */ + size_t realsize; /* actual size of block needed, including header */ const size_t block_size = ALIGNWORD(sizeof(struct block_t)); realsize = ALIGNWORD(size + block_size); @@ -131,15 +130,15 @@ static APC_HOTSPOT size_t sma_allocate(sma_header_t* header, zend_ulong size, ze return -1; } - prvnextfit = 0; /* initially null (no fit) */ - prv = BLOCKAT(ALIGNWORD(sizeof(sma_header_t))); + prvnextfit = 0; /* initially null (no fit) */ + prv = BLOCKAT(ALIGNWORD(sizeof(sma_header_t))); CHECK_CANARY(prv); while (prv->fnext != 0) { cur = BLOCKAT(prv->fnext); - CHECK_CANARY(cur); + CHECK_CANARY(cur); /* If it can fit realsize bytes in cur block, stop searching */ if (cur->size >= realsize) { @@ -161,27 +160,27 @@ static APC_HOTSPOT size_t sma_allocate(sma_header_t* header, zend_ulong size, ze if (cur->size == realsize || (cur->size > realsize && cur->size < (realsize + (MINBLOCKSIZE + fragment)))) { /* cur is big enough for realsize, but too small to split - unlink it */ - *(allocated) = cur->size - block_size; - prv->fnext = cur->fnext; - BLOCKAT(cur->fnext)->fprev = OFFSET(prv); - NEXT_SBLOCK(cur)->prev_size = 0; /* block is alloc'd */ + *(allocated) = cur->size - block_size; + prv->fnext = cur->fnext; + BLOCKAT(cur->fnext)->fprev = OFFSET(prv); + NEXT_SBLOCK(cur)->prev_size = 0; /* block is alloc'd */ } else { /* nextfit is too big; split it into two smaller blocks */ - block_t* nxt; /* the new block (chopped part of cur) */ - size_t oldsize; /* size of cur before split */ - - oldsize = cur->size; - cur->size = realsize; - *(allocated) = cur->size - block_size; - nxt = NEXT_SBLOCK(cur); - nxt->prev_size = 0; /* block is alloc'd */ - nxt->size = oldsize - realsize; /* and fix the size */ - NEXT_SBLOCK(nxt)->prev_size = nxt->size; /* adjust size */ + block_t* nxt; /* the new block (chopped part of cur) */ + size_t oldsize; /* size of cur before split */ + + oldsize = cur->size; + cur->size = realsize; + *(allocated) = cur->size - block_size; + nxt = NEXT_SBLOCK(cur); + nxt->prev_size = 0; /* block is alloc'd */ + nxt->size = oldsize - realsize; /* and fix the size */ + NEXT_SBLOCK(nxt)->prev_size = nxt->size; /* adjust size */ SET_CANARY(nxt); /* replace cur with next in free list */ - nxt->fnext = cur->fnext; - nxt->fprev = cur->fprev; + nxt->fnext = cur->fnext; + nxt->fprev = cur->fprev; BLOCKAT(nxt->fnext)->fprev = OFFSET(nxt); BLOCKAT(nxt->fprev)->fnext = OFFSET(nxt); #if 0 @@ -206,13 +205,14 @@ static APC_HOTSPOT size_t sma_allocate(sma_header_t* header, zend_ulong size, ze /* }}} */ /* {{{ sma_deallocate: deallocates the block at the given offset */ -static APC_HOTSPOT size_t sma_deallocate(void* shmaddr, size_t offset) +static APC_HOTSPOT size_t +sma_deallocate(void* shmaddr, size_t offset) { - sma_header_t* header; /* header of shared memory segment */ - block_t* cur; /* the new block to insert */ - block_t* prv; /* the block before cur */ - block_t* nxt; /* the block after cur */ - size_t size; /* size of deallocated block */ + sma_header_t* header; /* header of shared memory segment */ + block_t* cur; /* the new block to insert */ + block_t* prv; /* the block before cur */ + block_t* nxt; /* the block after cur */ + size_t size; /* size of deallocated block */ offset -= ALIGNWORD(sizeof(struct block_t)); assert(offset >= 0); @@ -227,13 +227,13 @@ static APC_HOTSPOT size_t sma_deallocate(void* shmaddr, size_t offset) if (cur->prev_size != 0) { /* remove prv from list */ - prv = PREV_SBLOCK(cur); + prv = PREV_SBLOCK(cur); BLOCKAT(prv->fnext)->fprev = prv->fprev; BLOCKAT(prv->fprev)->fnext = prv->fnext; /* cur and prv share an edge, combine them */ - prv->size +=cur->size; - - RESET_CANARY(cur); + prv->size += cur->size; + + RESET_CANARY(cur); cur = prv; } @@ -245,7 +245,7 @@ static APC_HOTSPOT size_t sma_deallocate(void* shmaddr, size_t offset) BLOCKAT(nxt->fprev)->fnext = nxt->fnext; cur->size += nxt->size; - CHECK_CANARY(nxt); + CHECK_CANARY(nxt); #if 0 nxt->id = -1; /* assert this or set it ? */ @@ -257,10 +257,10 @@ static APC_HOTSPOT size_t sma_deallocate(void* shmaddr, size_t offset) NEXT_SBLOCK(cur)->prev_size = cur->size; /* insert new block after prv */ - prv = BLOCKAT(ALIGNWORD(sizeof(sma_header_t))); - cur->fnext = prv->fnext; - prv->fnext = OFFSET(cur); - cur->fprev = OFFSET(prv); + prv = BLOCKAT(ALIGNWORD(sizeof(sma_header_t))); + cur->fnext = prv->fnext; + prv->fnext = OFFSET(cur); + cur->fprev = OFFSET(prv); BLOCKAT(cur->fnext)->fprev = OFFSET(cur); return size; @@ -268,31 +268,31 @@ static APC_HOTSPOT size_t sma_deallocate(void* shmaddr, size_t offset) /* }}} */ /* {{{ APC SMA API */ -PHP_APCU_API void apc_sma_api_init(apc_sma_t* sma, void** data, apc_sma_expunge_f expunge, int32_t num, zend_ulong size, char *mask) { - uint i; +PHP_APCU_API void +apc_sma_api_init(apc_sma_t* sma, void** data, apc_sma_expunge_f expunge, int32_t num, zend_ulong size, char* mask) +{ + uint i; if (sma->initialized) { return; } sma->initialized = 1; - sma->expunge = expunge; - sma->data = data; - + sma->expunge = expunge; + sma->data = data; + #if APC_MMAP /* * I don't think multiple anonymous mmaps makes any sense * so force sma_numseg to 1 in this case */ - if(!mask || - (mask && !strlen(mask)) || - (mask && !strcmp(mask, "/dev/zero"))) { + if (!mask || (mask && !strlen(mask)) || (mask && !strcmp(mask, "/dev/zero"))) { sma->num = 1; } else { sma->num = num > 0 ? num : DEFAULT_NUMSEG; } #else - sma->num = num > 0 ? num : DEFAULT_NUMSEG; + sma->num = num > 0 ? num : DEFAULT_NUMSEG; #endif sma->size = size > 0 ? size : DEFAULT_SEGSIZE; @@ -300,21 +300,18 @@ PHP_APCU_API void apc_sma_api_init(apc_sma_t* sma, void** data, apc_sma_expunge_ sma->segs = (apc_segment_t*) apc_emalloc((sma->num * sizeof(apc_segment_t))); for (i = 0; i < sma->num; i++) { - sma_header_t* header; - block_t *first, *empty, *last; - void* shmaddr; + sma_header_t* header; + block_t *first, *empty, *last; + void* shmaddr; #if APC_MMAP sma->segs[i] = apc_mmap(mask, sma->size); - if(sma->num != 1) - memcpy(&mask[strlen(mask)-6], "XXXXXX", 6); + if (sma->num != 1) + memcpy(&mask[strlen(mask) - 6], "XXXXXX", 6); #else - sma->segs[i] = apc_shm_attach( - apc_shm_create(i, sma->size), - sma->size - ); + sma->segs[i] = apc_shm_attach(apc_shm_create(i, sma->size), sma->size); #endif - + sma->segs[i].size = sma->size; shmaddr = sma->segs[i].shmaddr; @@ -322,30 +319,31 @@ PHP_APCU_API void apc_sma_api_init(apc_sma_t* sma, void** data, apc_sma_expunge_ header = (sma_header_t*) shmaddr; CREATE_LOCK(&header->sma_lock); header->segsize = sma->size; - header->avail = sma->size - ALIGNWORD(sizeof(sma_header_t)) - ALIGNWORD(sizeof(block_t)) - ALIGNWORD(sizeof(block_t)); + header->avail = + sma->size - ALIGNWORD(sizeof(sma_header_t)) - ALIGNWORD(sizeof(block_t)) - ALIGNWORD(sizeof(block_t)); - first = BLOCKAT(ALIGNWORD(sizeof(sma_header_t))); - first->size = 0; - first->fnext = ALIGNWORD(sizeof(sma_header_t)) + ALIGNWORD(sizeof(block_t)); - first->fprev = 0; + first = BLOCKAT(ALIGNWORD(sizeof(sma_header_t))); + first->size = 0; + first->fnext = ALIGNWORD(sizeof(sma_header_t)) + ALIGNWORD(sizeof(block_t)); + first->fprev = 0; first->prev_size = 0; SET_CANARY(first); #if 0 first->id = -1; #endif - empty = BLOCKAT(first->fnext); - empty->size = header->avail - ALIGNWORD(sizeof(block_t)); - empty->fnext = OFFSET(empty) + empty->size; - empty->fprev = ALIGNWORD(sizeof(sma_header_t)); + empty = BLOCKAT(first->fnext); + empty->size = header->avail - ALIGNWORD(sizeof(block_t)); + empty->fnext = OFFSET(empty) + empty->size; + empty->fprev = ALIGNWORD(sizeof(sma_header_t)); empty->prev_size = 0; SET_CANARY(empty); #if 0 empty->id = -1; #endif - last = BLOCKAT(empty->fnext); - last->size = 0; - last->fnext = 0; - last->fprev = OFFSET(empty); + last = BLOCKAT(empty->fnext); + last->size = 0; + last->fnext = 0; + last->fprev = OFFSET(empty); last->prev_size = empty->size; SET_CANARY(last); #if 0 @@ -354,8 +352,10 @@ PHP_APCU_API void apc_sma_api_init(apc_sma_t* sma, void** data, apc_sma_expunge_ } } -PHP_APCU_API void apc_sma_api_cleanup(apc_sma_t* sma) { - uint i; +PHP_APCU_API void +apc_sma_api_cleanup(apc_sma_t* sma) +{ + uint i; assert(sma->initialized); @@ -372,8 +372,10 @@ PHP_APCU_API void apc_sma_api_cleanup(apc_sma_t* sma) { apc_efree(sma->segs); } -PHP_APCU_API void* apc_sma_api_malloc_ex(apc_sma_t* sma, zend_ulong n, zend_ulong fragment, zend_ulong* allocated) { - size_t off; +PHP_APCU_API void* +apc_sma_api_malloc_ex(apc_sma_t* sma, zend_ulong n, zend_ulong fragment, zend_ulong* allocated) +{ + size_t off; uint i; int nuked = 0; @@ -384,24 +386,23 @@ PHP_APCU_API void* apc_sma_api_malloc_ex(apc_sma_t* sma, zend_ulong n, zend_ulon off = sma_allocate(SMA_HDR(sma, sma->last), n, fragment, allocated); - if(off == -1) { + if (off == -1) { /* retry failed allocation after we expunge */ WUNLOCK(&SMA_LCK(sma, sma->last)); - sma->expunge( - *(sma->data), (n+fragment)); + sma->expunge(*(sma->data), (n + fragment)); WLOCK(&SMA_LCK(sma, sma->last)); off = sma_allocate(SMA_HDR(sma, sma->last), n, fragment, allocated); } if (off != -1) { - void* p = (void *)(SMA_ADDR(sma, sma->last) + off); + void* p = (void*) (SMA_ADDR(sma, sma->last) + off); WUNLOCK(&SMA_LCK(sma, sma->last)); #ifdef VALGRIND_MALLOCLIKE_BLOCK VALGRIND_MALLOCLIKE_BLOCK(p, n, 0, 0); #endif return p; } - + WUNLOCK(&SMA_LCK(sma, sma->last)); for (i = 0; i < sma->num; i++) { @@ -410,16 +411,15 @@ PHP_APCU_API void* apc_sma_api_malloc_ex(apc_sma_t* sma, zend_ulong n, zend_ulon } WLOCK(&SMA_LCK(sma, i)); off = sma_allocate(SMA_HDR(sma, i), n, fragment, allocated); - if(off == -1) { + if (off == -1) { /* retry failed allocation after we expunge */ WUNLOCK(&SMA_LCK(sma, i)); - sma->expunge( - *(sma->data), (n+fragment)); + sma->expunge(*(sma->data), (n + fragment)); WLOCK(&SMA_LCK(sma, i)); off = sma_allocate(SMA_HDR(sma, i), n, fragment, allocated); } if (off != -1) { - void* p = (void *)(SMA_ADDR(sma, i) + off); + void* p = (void*) (SMA_ADDR(sma, i) + off); WUNLOCK(&SMA_LCK(sma, i)); sma->last = i; #ifdef VALGRIND_MALLOCLIKE_BLOCK @@ -431,8 +431,8 @@ PHP_APCU_API void* apc_sma_api_malloc_ex(apc_sma_t* sma, zend_ulong n, zend_ulon } /* I've tried being nice, but now you're just asking for it */ - if(!nuked) { - sma->expunge(*(sma->data), (n+fragment)); + if (!nuked) { + sma->expunge(*(sma->data), (n + fragment)); nuked = 1; goto restart; } @@ -442,41 +442,45 @@ PHP_APCU_API void* apc_sma_api_malloc_ex(apc_sma_t* sma, zend_ulong n, zend_ulon return NULL; } -PHP_APCU_API void* apc_sma_api_malloc(apc_sma_t* sma, zend_ulong n) +PHP_APCU_API void* +apc_sma_api_malloc(apc_sma_t* sma, zend_ulong n) { - zend_ulong allocated; - return apc_sma_api_malloc_ex( - sma, n, MINBLOCKSIZE, &allocated); + zend_ulong allocated; + return apc_sma_api_malloc_ex(sma, n, MINBLOCKSIZE, &allocated); } -PHP_APCU_API void* apc_sma_api_realloc(apc_sma_t* sma, void* p, zend_ulong n) { - apc_sma_api_free(sma, p); - return apc_sma_api_malloc( - sma, n); +PHP_APCU_API void* +apc_sma_api_realloc(apc_sma_t* sma, void* p, zend_ulong n) +{ + apc_sma_api_free(sma, p); + return apc_sma_api_malloc(sma, n); } -PHP_APCU_API char* apc_sma_api_strdup(apc_sma_t* sma, const char* s) { - void* q; +PHP_APCU_API char* +apc_sma_api_strdup(apc_sma_t* sma, const char* s) +{ + void* q; int len; - if(!s) { - return NULL; - } + if (!s) { + return NULL; + } - len = strlen(s)+1; - q = apc_sma_api_malloc( - sma, len); + len = strlen(s) + 1; + q = apc_sma_api_malloc(sma, len); - if(!q) { - return NULL; - } + if (!q) { + return NULL; + } memcpy(q, s, len); return q; } -PHP_APCU_API void apc_sma_api_free(apc_sma_t* sma, void* p) { - uint i; +PHP_APCU_API void +apc_sma_api_free(apc_sma_t* sma, void* p) +{ + uint i; size_t offset; if (p == NULL) { @@ -486,8 +490,8 @@ PHP_APCU_API void apc_sma_api_free(apc_sma_t* sma, void* p) { assert(sma->initialized); for (i = 0; i < sma->num; i++) { - offset = (size_t)((char *)p - SMA_ADDR(sma, i)); - if (p >= (void*)SMA_ADDR(sma, i) && offset < sma->size) { + offset = (size_t)((char*) p - SMA_ADDR(sma, i)); + if (p >= (void*) SMA_ADDR(sma, i) && offset < sma->size) { WLOCK(&SMA_LCK(sma, i)); sma_deallocate(SMA_HDR(sma, i), offset); WUNLOCK(&SMA_LCK(sma, i)); @@ -502,25 +506,28 @@ PHP_APCU_API void apc_sma_api_free(apc_sma_t* sma, void* p) { } #ifdef APC_MEMPROTECT -PHP_APCU_API void* apc_sma_api_protect(apc_sma_t* sma, void* p) { - unsigned int i = 0; +PHP_APCU_API void* +apc_sma_api_protect(apc_sma_t* sma, void* p) +{ + unsigned int i = 0; size_t offset; if (p == NULL) { return NULL; } - if(SMA_RO(sma, sma->last) == NULL) return p; + if (SMA_RO(sma, sma->last) == NULL) + return p; - offset = (size_t)((char *)p - SMA_ADDR(sma, sma->last)); + offset = (size_t)((char*) p - SMA_ADDR(sma, sma->last)); - if(p >= (void*)SMA_ADDR(sma, sma->last) && offset < sma->size) { + if (p >= (void*) SMA_ADDR(sma, sma->last) && offset < sma->size) { return SMA_RO(sma, sma->last) + offset; } for (i = 0; i < sma->num; i++) { - offset = (size_t)((char *)p - SMA_ADDR(sma, i)); - if (p >= (void*)SMA_ADDR(sma, i) && offset < sma->size) { + offset = (size_t)((char*) p - SMA_ADDR(sma, i)); + if (p >= (void*) SMA_ADDR(sma, i) && offset < sma->size) { return SMA_RO(sma, i) + offset; } } @@ -528,25 +535,28 @@ PHP_APCU_API void* apc_sma_api_protect(apc_sma_t* sma, void* p) { return NULL; } -PHP_APCU_API void* apc_sma_api_unprotect(apc_sma_t* sma, void* p){ - unsigned int i = 0; +PHP_APCU_API void* +apc_sma_api_unprotect(apc_sma_t* sma, void* p) +{ + unsigned int i = 0; size_t offset; if (p == NULL) { return NULL; } - if(SMA_RO(sma, sma->last) == NULL) return p; + if (SMA_RO(sma, sma->last) == NULL) + return p; - offset = (size_t)((char *)p - SMA_RO(sma, sma->last)); + offset = (size_t)((char*) p - SMA_RO(sma, sma->last)); - if(p >= (void*)SMA_RO(sma, sma->last) && offset < sma->size) { + if (p >= (void*) SMA_RO(sma, sma->last) && offset < sma->size) { return SMA_ADDR(sma, sma->last) + offset; } for (i = 0; i < sma->num; i++) { - offset = (size_t)((char *)p - SMA_RO(sma, i)); - if (p >= (void*)SMA_RO(sma, i) && offset < sma->size) { + offset = (size_t)((char*) p - SMA_RO(sma, i)); + if (p >= (void*) SMA_RO(sma, i) && offset < sma->size) { return SMA_ADDR(sma, i) + offset; } } @@ -554,12 +564,22 @@ PHP_APCU_API void* apc_sma_api_unprotect(apc_sma_t* sma, void* p){ return NULL; } #else -PHP_APCU_API void* apc_sma_api_protect(apc_sma_t* sma, void *p) { return p; } -PHP_APCU_API void* apc_sma_api_unprotect(apc_sma_t* sma, void *p) { return p; } +PHP_APCU_API void* +apc_sma_api_protect(apc_sma_t* sma, void* p) +{ + return p; +} +PHP_APCU_API void* +apc_sma_api_unprotect(apc_sma_t* sma, void* p) +{ + return p; +} #endif -PHP_APCU_API apc_sma_info_t* apc_sma_api_info(apc_sma_t* sma, zend_bool limited) { - apc_sma_info_t* info; +PHP_APCU_API apc_sma_info_t* +apc_sma_api_info(apc_sma_t* sma, zend_bool limited) +{ + apc_sma_info_t* info; apc_sma_link_t** link; uint i; char* shmaddr; @@ -569,38 +589,39 @@ PHP_APCU_API apc_sma_info_t* apc_sma_api_info(apc_sma_t* sma, zend_bool limited) return NULL; } - info = (apc_sma_info_t*) apc_emalloc(sizeof(apc_sma_info_t)); + info = (apc_sma_info_t*) apc_emalloc(sizeof(apc_sma_info_t)); info->num_seg = sma->num; - info->seg_size = sma->size - (ALIGNWORD(sizeof(sma_header_t)) + ALIGNWORD(sizeof(block_t)) + ALIGNWORD(sizeof(block_t))); + info->seg_size = + sma->size - (ALIGNWORD(sizeof(sma_header_t)) + ALIGNWORD(sizeof(block_t)) + ALIGNWORD(sizeof(block_t))); info->list = apc_emalloc(info->num_seg * sizeof(apc_sma_link_t*)); for (i = 0; i < sma->num; i++) { info->list[i] = NULL; } - if(limited) { - return info; - } + if (limited) { + return info; + } /* For each segment */ for (i = 0; i < sma->num; i++) { RLOCK(&SMA_LCK(sma, i)); shmaddr = SMA_ADDR(sma, i); - prv = BLOCKAT(ALIGNWORD(sizeof(sma_header_t))); + prv = BLOCKAT(ALIGNWORD(sizeof(sma_header_t))); link = &info->list[i]; /* For each block in this segment */ while (BLOCKAT(prv->fnext)->fnext != 0) { block_t* cur = BLOCKAT(prv->fnext); - - CHECK_CANARY(cur); - *link = apc_emalloc(sizeof(apc_sma_link_t)); - (*link)->size = cur->size; + CHECK_CANARY(cur); + + *link = apc_emalloc(sizeof(apc_sma_link_t)); + (*link)->size = cur->size; (*link)->offset = prv->fnext; - (*link)->next = NULL; - link = &(*link)->next; + (*link)->next = NULL; + link = &(*link)->next; prv = cur; } @@ -610,14 +631,16 @@ PHP_APCU_API apc_sma_info_t* apc_sma_api_info(apc_sma_t* sma, zend_bool limited) return info; } -PHP_APCU_API void apc_sma_api_free_info(apc_sma_t* sma, apc_sma_info_t* info) { - int i; +PHP_APCU_API void +apc_sma_api_free_info(apc_sma_t* sma, apc_sma_info_t* info) +{ + int i; for (i = 0; i < info->num_seg; i++) { apc_sma_link_t* p = info->list[i]; while (p) { apc_sma_link_t* q = p; - p = p->next; + p = p->next; apc_efree(q); } } @@ -625,8 +648,10 @@ PHP_APCU_API void apc_sma_api_free_info(apc_sma_t* sma, apc_sma_info_t* info) { apc_efree(info); } -PHP_APCU_API zend_ulong apc_sma_api_get_avail_mem(apc_sma_t* sma) { - size_t avail_mem = 0; +PHP_APCU_API zend_ulong +apc_sma_api_get_avail_mem(apc_sma_t* sma) +{ + size_t avail_mem = 0; uint i; for (i = 0; i < sma->num; i++) { @@ -636,28 +661,31 @@ PHP_APCU_API zend_ulong apc_sma_api_get_avail_mem(apc_sma_t* sma) { return avail_mem; } -PHP_APCU_API zend_bool apc_sma_api_get_avail_size(apc_sma_t* sma, size_t size) { - uint i; +PHP_APCU_API zend_bool +apc_sma_api_get_avail_size(apc_sma_t* sma, size_t size) +{ + uint i; for (i = 0; i < sma->num; i++) { - sma_header_t* header = SMA_HDR(sma, i); - if (header->avail > size) { - return 1; - } + sma_header_t* header = SMA_HDR(sma, i); + if (header->avail > size) { + return 1; + } } return 0; } -PHP_APCU_API void apc_sma_api_check_integrity(apc_sma_t* sma) +PHP_APCU_API void +apc_sma_api_check_integrity(apc_sma_t* sma) { /* dummy */ } /* {{{ APC SMA */ -apc_sma_api_impl(apc_sma, &apc_user_cache, apc_cache_default_expunge); +apc_sma_api_impl(apc_sma, &apc_user_cache, apc_cache_default_expunge); /* }}} */ - /* }}} */ +/* }}} */ /* * Local variables: diff --git a/apc_sma_api.h b/apc_sma_api.h index c282feb3..24eef734 100644 --- a/apc_sma_api.h +++ b/apc_sma_api.h @@ -27,98 +27,94 @@ #ifndef HAVE_APC_SMA_API_H #define HAVE_APC_SMA_API_H /* {{{ SMA API - APC SMA API provides support for shared memory allocators to external libraries ( and to APC ) + APC SMA API provides support for shared memory allocators to external libraries ( and to APC ) Skip to the bottom macros for error free usage of the SMA API */ /* {{{ struct definition: apc_segment_t */ typedef struct _apc_segment_t { - size_t size; /* size of this segment */ - void* shmaddr; /* address of shared memory */ + size_t size; /* size of this segment */ + void* shmaddr; /* address of shared memory */ #ifdef APC_MEMPROTECT - void* roaddr; /* read only (mprotect'd) address */ + void* roaddr; /* read only (mprotect'd) address */ #endif } apc_segment_t; /* }}} */ /* {{{ struct definition: apc_sma_link_t */ typedef struct apc_sma_link_t apc_sma_link_t; struct apc_sma_link_t { - zend_long size; /* size of this free block */ - zend_long offset; /* offset in segment of this block */ - apc_sma_link_t* next; /* link to next free block */ + zend_long size; /* size of this free block */ + zend_long offset; /* offset in segment of this block */ + apc_sma_link_t* next; /* link to next free block */ }; /* }}} */ /* {{{ struct definition: apc_sma_info_t */ typedef struct apc_sma_info_t apc_sma_info_t; struct apc_sma_info_t { - int num_seg; /* number of segments */ - size_t seg_size; /* segment size */ - apc_sma_link_t** list; /* one list per segment of links */ + int num_seg; /* number of segments */ + size_t seg_size; /* segment size */ + apc_sma_link_t** list; /* one list per segment of links */ }; /* }}} */ /* {{{ function definitions for SMA API objects */ -typedef void (*apc_sma_init_f) (int32_t num, zend_ulong size, char *mask); -typedef void (*apc_sma_cleanup_f) (); -typedef void* (*apc_sma_malloc_f) (zend_ulong size); -typedef void* (*apc_sma_malloc_ex_f) (zend_ulong size, zend_ulong fragment, zend_ulong *allocated); -typedef void* (*apc_sma_realloc_f) (void* p, zend_ulong size); -typedef char* (*apc_sma_strdup_f) (const char* str); -typedef void (*apc_sma_free_f) (void *p); -typedef void* (*apc_sma_protect_f) (void* p); -typedef void* (*apc_sma_unprotect_f) (void* p); -typedef apc_sma_info_t* (*apc_sma_info_f) (zend_bool limited); -typedef void (*apc_sma_free_info_f) (apc_sma_info_t *info); -typedef zend_ulong (*apc_sma_get_avail_mem_f) (void); -typedef zend_bool (*apc_sma_get_avail_size_f) (zend_ulong size); -typedef void (*apc_sma_check_integrity_f) (void); +typedef void (*apc_sma_init_f)(int32_t num, zend_ulong size, char* mask); +typedef void (*apc_sma_cleanup_f)(); +typedef void* (*apc_sma_malloc_f)(zend_ulong size); +typedef void* (*apc_sma_malloc_ex_f)(zend_ulong size, zend_ulong fragment, zend_ulong* allocated); +typedef void* (*apc_sma_realloc_f)(void* p, zend_ulong size); +typedef char* (*apc_sma_strdup_f)(const char* str); +typedef void (*apc_sma_free_f)(void* p); +typedef void* (*apc_sma_protect_f)(void* p); +typedef void* (*apc_sma_unprotect_f)(void* p); +typedef apc_sma_info_t* (*apc_sma_info_f)(zend_bool limited); +typedef void (*apc_sma_free_info_f)(apc_sma_info_t* info); +typedef zend_ulong (*apc_sma_get_avail_mem_f)(void); +typedef zend_bool (*apc_sma_get_avail_size_f)(zend_ulong size); +typedef void (*apc_sma_check_integrity_f)(void); typedef void (*apc_sma_expunge_f)(void* pointer, zend_ulong size); /* }}} */ /* {{{ struct definition: apc_sma_t */ typedef struct _apc_sma_t { - zend_bool initialized; /* flag to indicate this sma has been intialized */ + zend_bool initialized; /* flag to indicate this sma has been intialized */ /* functions */ - apc_sma_init_f init; /* init */ - apc_sma_cleanup_f cleanup; /* cleanup */ - apc_sma_malloc_f smalloc; /* malloc */ - apc_sma_malloc_ex_f malloc_ex; /* malloc_ex */ - apc_sma_realloc_f realloc; /* realloc */ - apc_sma_strdup_f strdup; /* strdup */ - apc_sma_free_f sfree; /* free */ - apc_sma_protect_f protect; /* protect */ - apc_sma_unprotect_f unprotect; /* unprotect */ - apc_sma_info_f info; /* info */ - apc_sma_free_info_f free_info; /* free info */ - apc_sma_get_avail_mem_f get_avail_mem; /* get avail mem */ - apc_sma_get_avail_size_f get_avail_size; /* get avail size */ - apc_sma_check_integrity_f check_integrity; /* check integrity */ - - /* callback */ - apc_sma_expunge_f expunge; /* expunge */ - void** data; /* data */ - + apc_sma_init_f init; /* init */ + apc_sma_cleanup_f cleanup; /* cleanup */ + apc_sma_malloc_f smalloc; /* malloc */ + apc_sma_malloc_ex_f malloc_ex; /* malloc_ex */ + apc_sma_realloc_f realloc; /* realloc */ + apc_sma_strdup_f strdup; /* strdup */ + apc_sma_free_f sfree; /* free */ + apc_sma_protect_f protect; /* protect */ + apc_sma_unprotect_f unprotect; /* unprotect */ + apc_sma_info_f info; /* info */ + apc_sma_free_info_f free_info; /* free info */ + apc_sma_get_avail_mem_f get_avail_mem; /* get avail mem */ + apc_sma_get_avail_size_f get_avail_size; /* get avail size */ + apc_sma_check_integrity_f check_integrity; /* check integrity */ + + /* callback */ + apc_sma_expunge_f expunge; /* expunge */ + void** data; /* data */ + /* info */ - int32_t num; /* number of segments */ - zend_ulong size; /* segment size */ - int32_t last; /* last segment */ + int32_t num; /* number of segments */ + zend_ulong size; /* segment size */ + int32_t last; /* last segment */ /* segments */ - apc_segment_t* segs; /* segments */ -} apc_sma_t; /* }}} */ + apc_segment_t* segs; /* segments */ +} apc_sma_t; /* }}} */ /* * apc_sma_api_init will initialize a shared memory allocator with num segments of the given size * * should be called once per allocator per process */ -PHP_APCU_API void apc_sma_api_init(apc_sma_t* sma, - void** data, - apc_sma_expunge_f expunge, - int32_t num, - zend_ulong size, - char *mask); +PHP_APCU_API void +apc_sma_api_init(apc_sma_t* sma, void** data, apc_sma_expunge_f expunge, int32_t num, zend_ulong size, char* mask); /* * apc_sma_api_cleanup will free the sma allocator @@ -128,70 +124,57 @@ PHP_APCU_API void apc_sma_api_cleanup(apc_sma_t* sma); /* * apc_smap_api_malloc will allocate a block from the sma of the given size */ -PHP_APCU_API void* apc_sma_api_malloc(apc_sma_t* sma, - zend_ulong size); +PHP_APCU_API void* apc_sma_api_malloc(apc_sma_t* sma, zend_ulong size); /* * apc_sma_api_malloc_ex will allocate a block from the sma of the given size */ -PHP_APCU_API void* apc_sma_api_malloc_ex(apc_sma_t* sma, - zend_ulong size, - zend_ulong fragment, - zend_ulong* allocated); +PHP_APCU_API void* apc_sma_api_malloc_ex(apc_sma_t* sma, zend_ulong size, zend_ulong fragment, zend_ulong* allocated); /* * apc_sma_api_realloc will reallocate p using a new block from sma (freeing the original p) */ -PHP_APCU_API void* apc_sma_api_realloc(apc_sma_t* sma, - void* p, - zend_ulong size); +PHP_APCU_API void* apc_sma_api_realloc(apc_sma_t* sma, void* p, zend_ulong size); /* * apc_sma_api_strdup will duplicate the given string into a block from sma */ -PHP_APCU_API char* apc_sma_api_strdup(apc_sma_t* sma, - const char* s); +PHP_APCU_API char* apc_sma_api_strdup(apc_sma_t* sma, const char* s); /* * apc_sma_api_free will free p (which should be a pointer to a block allocated from sma) */ -PHP_APCU_API void apc_sma_api_free(apc_sma_t* sma, - void* p); +PHP_APCU_API void apc_sma_api_free(apc_sma_t* sma, void* p); /* * apc_sma_api_protect will protect p (which should be a pointer to a block allocated from sma) */ -PHP_APCU_API void* apc_sma_api_protect(apc_sma_t* sma, - void* p); +PHP_APCU_API void* apc_sma_api_protect(apc_sma_t* sma, void* p); /* * apc_sma_api_protect will uprotect p (which should be a pointer to a block allocated from sma) */ -PHP_APCU_API void* apc_sma_api_unprotect(apc_sma_t* sma, - void *p); +PHP_APCU_API void* apc_sma_api_unprotect(apc_sma_t* sma, void* p); /* * apc_sma_api_info returns information about the allocator */ -PHP_APCU_API apc_sma_info_t* apc_sma_api_info(apc_sma_t* sma, - zend_bool limited); +PHP_APCU_API apc_sma_info_t* apc_sma_api_info(apc_sma_t* sma, zend_bool limited); /* * apc_sma_api_info_free_info is for freeing apc_sma_info_t* returned by apc_sma_api_info */ -PHP_APCU_API void apc_sma_api_free_info(apc_sma_t* sma, - apc_sma_info_t* info); +PHP_APCU_API void apc_sma_api_free_info(apc_sma_t* sma, apc_sma_info_t* info); /* * apc_sma_api_get_avail_mem will return the amount of memory available left to sma */ -PHP_APCU_API zend_ulong apc_sma_api_get_avail_mem(apc_sma_t* sma); +PHP_APCU_API zend_ulong apc_sma_api_get_avail_mem(apc_sma_t* sma); /* * apc_sma_api_get_avail_size will return true if at least size bytes are available to the sma */ -PHP_APCU_API zend_bool apc_sma_api_get_avail_size(apc_sma_t* sma, - size_t size); +PHP_APCU_API zend_bool apc_sma_api_get_avail_size(apc_sma_t* sma, size_t size); /* * apc_sma_api_check_integrity will check the integrity of sma @@ -199,8 +182,14 @@ PHP_APCU_API zend_bool apc_sma_api_get_avail_size(apc_sma_t* sma, PHP_APCU_API void apc_sma_api_check_integrity(apc_sma_t* sma); /* }}} */ /* {{{ ALIGNWORD: pad up x, aligned to the system's word boundary */ -typedef union { void* p; int i; long l; double d; void (*f)(void); } apc_word_t; -#define ALIGNSIZE(x, size) ((size) * (1 + (((x)-1)/(size)))) +typedef union { + void* p; + int i; + long l; + double d; + void (*f)(void); +} apc_word_t; +#define ALIGNSIZE(x, size) ((size) * (1 + (((x) -1) / (size)))) #define ALIGNWORD(x) ALIGNSIZE(x, sizeof(apc_word_t)) /* }}} */ @@ -215,78 +204,107 @@ typedef union { void* p; int i; long l; double d; void (*f)(void); } apc_word_t; */ /* {{{ Implementor macros */ -#define apc_sma_api_name(name) name -#define apc_sma_api_ptr(name) &apc_sma_api_name(name) +#define apc_sma_api_name(name) name +#define apc_sma_api_ptr(name) &apc_sma_api_name(name) #define apc_sma_api_func(name, func) name##_##func /* {{{ Call in a header somewhere to extern all sma functions */ -#define apc_sma_api_decl(name) \ - PHP_APCU_API void apc_sma_api_func(name, init)(int32_t num, zend_ulong size, char* mask); \ - PHP_APCU_API void apc_sma_api_func(name, cleanup)(); \ - PHP_APCU_API void* apc_sma_api_func(name, malloc)(zend_ulong size); \ - PHP_APCU_API void* apc_sma_api_func(name, malloc_ex)(zend_ulong size, zend_ulong fragment, zend_ulong* allocated); \ - PHP_APCU_API void* apc_sma_api_func(name, realloc)(void* p, zend_ulong size); \ - PHP_APCU_API char* apc_sma_api_func(name, strdup)(const char* s); \ - PHP_APCU_API void apc_sma_api_func(name, free)(void* p); \ - PHP_APCU_API void* apc_sma_api_func(name, protect)(void* p); \ - PHP_APCU_API void* apc_sma_api_func(name, unprotect)(void* p); \ - PHP_APCU_API apc_sma_info_t* apc_sma_api_func(name, info)(zend_bool limited); \ - PHP_APCU_API void apc_sma_api_func(name, free_info)(apc_sma_info_t* info); \ - PHP_APCU_API zend_ulong apc_sma_api_func(name, get_avail_mem)(void); \ - PHP_APCU_API zend_bool apc_sma_api_func(name, get_avail_size)(zend_ulong size); \ +#define apc_sma_api_decl(name) \ + PHP_APCU_API void apc_sma_api_func(name, init)(int32_t num, zend_ulong size, char* mask); \ + PHP_APCU_API void apc_sma_api_func(name, cleanup)(); \ + PHP_APCU_API void* apc_sma_api_func(name, malloc)(zend_ulong size); \ + PHP_APCU_API void* apc_sma_api_func(name, malloc_ex)(zend_ulong size, zend_ulong fragment, \ + zend_ulong * allocated); \ + PHP_APCU_API void* apc_sma_api_func(name, realloc)(void* p, zend_ulong size); \ + PHP_APCU_API char* apc_sma_api_func(name, strdup)(const char* s); \ + PHP_APCU_API void apc_sma_api_func(name, free)(void* p); \ + PHP_APCU_API void* apc_sma_api_func(name, protect)(void* p); \ + PHP_APCU_API void* apc_sma_api_func(name, unprotect)(void* p); \ + PHP_APCU_API apc_sma_info_t* apc_sma_api_func(name, info)(zend_bool limited); \ + PHP_APCU_API void apc_sma_api_func(name, free_info)(apc_sma_info_t * info); \ + PHP_APCU_API zend_ulong apc_sma_api_func(name, get_avail_mem)(void); \ + PHP_APCU_API zend_bool apc_sma_api_func(name, get_avail_size)(zend_ulong size); \ PHP_APCU_API void apc_sma_api_func(name, check_integrity)(void); /* }}} */ /* {{{ Call in a compilation unit */ -#define apc_sma_api_impl(name, data, expunge) \ - apc_sma_t apc_sma_api_name(name) = {0, \ - &apc_sma_api_func(name, init), \ - &apc_sma_api_func(name, cleanup), \ - &apc_sma_api_func(name, malloc), \ - &apc_sma_api_func(name, malloc_ex), \ - &apc_sma_api_func(name, realloc), \ - &apc_sma_api_func(name, strdup), \ - &apc_sma_api_func(name, free), \ - &apc_sma_api_func(name, protect), \ - &apc_sma_api_func(name, unprotect), \ - &apc_sma_api_func(name, info), \ - &apc_sma_api_func(name, free_info), \ - &apc_sma_api_func(name, get_avail_mem), \ - &apc_sma_api_func(name, get_avail_size), \ - &apc_sma_api_func(name, check_integrity), \ - }; \ - PHP_APCU_API void apc_sma_api_func(name, init)(int32_t num, zend_ulong size, char* mask) \ - { apc_sma_api_init(apc_sma_api_ptr(name), (void**) data, (apc_sma_expunge_f) expunge, num, size, mask); } \ - PHP_APCU_API void apc_sma_api_func(name, cleanup)() \ - { apc_sma_api_cleanup(apc_sma_api_ptr(name)); } \ - PHP_APCU_API void* apc_sma_api_func(name, malloc)(zend_ulong size) \ - { return apc_sma_api_malloc(apc_sma_api_ptr(name), size); } \ - PHP_APCU_API void* apc_sma_api_func(name, malloc_ex)(zend_ulong size, zend_ulong fragment, zend_ulong* allocated) \ - { return apc_sma_api_malloc_ex(apc_sma_api_ptr(name), size, fragment, allocated); } \ - PHP_APCU_API void* apc_sma_api_func(name, realloc)(void* p, zend_ulong size) \ - { return apc_sma_api_realloc(apc_sma_api_ptr(name), p, size); } \ - PHP_APCU_API char* apc_sma_api_func(name, strdup)(const char* s) \ - { return apc_sma_api_strdup(apc_sma_api_ptr(name), s); } \ - PHP_APCU_API void apc_sma_api_func(name, free)(void* p) \ - { apc_sma_api_free(apc_sma_api_ptr(name), p); } \ - PHP_APCU_API void* apc_sma_api_func(name, protect)(void* p) \ - { return apc_sma_api_protect(apc_sma_api_ptr(name), p); } \ - PHP_APCU_API void* apc_sma_api_func(name, unprotect)(void* p) \ - { return apc_sma_api_unprotect(apc_sma_api_ptr(name), p); } \ - PHP_APCU_API apc_sma_info_t* apc_sma_api_func(name, info)(zend_bool limited) \ - { return apc_sma_api_info(apc_sma_api_ptr(name), limited); } \ - PHP_APCU_API void apc_sma_api_func(name, free_info)(apc_sma_info_t* info) \ - { apc_sma_api_free_info(apc_sma_api_ptr(name), info); } \ - PHP_APCU_API zend_ulong apc_sma_api_func(name, get_avail_mem)() \ - { return apc_sma_api_get_avail_mem(apc_sma_api_ptr(name)); } \ - PHP_APCU_API zend_bool apc_sma_api_func(name, get_avail_size)(zend_ulong size) \ - { return apc_sma_api_get_avail_size(apc_sma_api_ptr(name), size); } \ - PHP_APCU_API void apc_sma_api_func(name, check_integrity)() \ - { apc_sma_api_check_integrity(apc_sma_api_ptr(name)); } /* }}} */ +#define apc_sma_api_impl(name, data, expunge) \ + apc_sma_t apc_sma_api_name(name) = { \ + 0, \ + &apc_sma_api_func(name, init), \ + &apc_sma_api_func(name, cleanup), \ + &apc_sma_api_func(name, malloc), \ + &apc_sma_api_func(name, malloc_ex), \ + &apc_sma_api_func(name, realloc), \ + &apc_sma_api_func(name, strdup), \ + &apc_sma_api_func(name, free), \ + &apc_sma_api_func(name, protect), \ + &apc_sma_api_func(name, unprotect), \ + &apc_sma_api_func(name, info), \ + &apc_sma_api_func(name, free_info), \ + &apc_sma_api_func(name, get_avail_mem), \ + &apc_sma_api_func(name, get_avail_size), \ + &apc_sma_api_func(name, check_integrity), \ + }; \ + PHP_APCU_API void apc_sma_api_func(name, init)(int32_t num, zend_ulong size, char* mask) \ + { \ + apc_sma_api_init(apc_sma_api_ptr(name), (void**) data, (apc_sma_expunge_f) expunge, num, size, mask); \ + } \ + PHP_APCU_API void apc_sma_api_func(name, cleanup)() \ + { \ + apc_sma_api_cleanup(apc_sma_api_ptr(name)); \ + } \ + PHP_APCU_API void* apc_sma_api_func(name, malloc)(zend_ulong size) \ + { \ + return apc_sma_api_malloc(apc_sma_api_ptr(name), size); \ + } \ + PHP_APCU_API void* apc_sma_api_func(name, malloc_ex)(zend_ulong size, zend_ulong fragment, zend_ulong * allocated) \ + { \ + return apc_sma_api_malloc_ex(apc_sma_api_ptr(name), size, fragment, allocated); \ + } \ + PHP_APCU_API void* apc_sma_api_func(name, realloc)(void* p, zend_ulong size) \ + { \ + return apc_sma_api_realloc(apc_sma_api_ptr(name), p, size); \ + } \ + PHP_APCU_API char* apc_sma_api_func(name, strdup)(const char* s) \ + { \ + return apc_sma_api_strdup(apc_sma_api_ptr(name), s); \ + } \ + PHP_APCU_API void apc_sma_api_func(name, free)(void* p) \ + { \ + apc_sma_api_free(apc_sma_api_ptr(name), p); \ + } \ + PHP_APCU_API void* apc_sma_api_func(name, protect)(void* p) \ + { \ + return apc_sma_api_protect(apc_sma_api_ptr(name), p); \ + } \ + PHP_APCU_API void* apc_sma_api_func(name, unprotect)(void* p) \ + { \ + return apc_sma_api_unprotect(apc_sma_api_ptr(name), p); \ + } \ + PHP_APCU_API apc_sma_info_t* apc_sma_api_func(name, info)(zend_bool limited) \ + { \ + return apc_sma_api_info(apc_sma_api_ptr(name), limited); \ + } \ + PHP_APCU_API void apc_sma_api_func(name, free_info)(apc_sma_info_t * info) \ + { \ + apc_sma_api_free_info(apc_sma_api_ptr(name), info); \ + } \ + PHP_APCU_API zend_ulong apc_sma_api_func(name, get_avail_mem)() \ + { \ + return apc_sma_api_get_avail_mem(apc_sma_api_ptr(name)); \ + } \ + PHP_APCU_API zend_bool apc_sma_api_func(name, get_avail_size)(zend_ulong size) \ + { \ + return apc_sma_api_get_avail_size(apc_sma_api_ptr(name), size); \ + } \ + PHP_APCU_API void apc_sma_api_func(name, check_integrity)() \ + { \ + apc_sma_api_check_integrity(apc_sma_api_ptr(name)); \ + } /* }}} */ /* {{{ Call wherever access to the SMA object is required */ -#define apc_sma_api_extern(name) extern apc_sma_t apc_sma_api_name(name) /* }}} */ +#define apc_sma_api_extern(name) extern apc_sma_t apc_sma_api_name(name) /* }}} */ /* }}} */ #endif - diff --git a/apc_stack.c b/apc_stack.c index 094f9715..3402dc5d 100644 --- a/apc_stack.c +++ b/apc_stack.c @@ -36,18 +36,20 @@ struct apc_stack_t { int size; }; -apc_stack_t* apc_stack_create(int size_hint) +apc_stack_t* +apc_stack_create(int size_hint) { apc_stack_t* stack = (apc_stack_t*) apc_emalloc(sizeof(apc_stack_t)); stack->capacity = (size_hint > 0) ? size_hint : 10; - stack->size = 0; - stack->data = (void**) apc_emalloc(sizeof(void*) * stack->capacity); + stack->size = 0; + stack->data = (void**) apc_emalloc(sizeof(void*) * stack->capacity); return stack; } -void apc_stack_destroy(apc_stack_t* stack) +void +apc_stack_destroy(apc_stack_t* stack) { if (stack != NULL) { apc_efree(stack->data); @@ -55,47 +57,52 @@ void apc_stack_destroy(apc_stack_t* stack) } } -void apc_stack_clear(apc_stack_t* stack) +void +apc_stack_clear(apc_stack_t* stack) { assert(stack != NULL); stack->size = 0; } -void apc_stack_push(apc_stack_t* stack, void* item) +void +apc_stack_push(apc_stack_t* stack, void* item) { assert(stack != NULL); if (stack->size == stack->capacity) { stack->capacity *= 2; - stack->data = apc_erealloc(stack->data, sizeof(void*)*stack->capacity); + stack->data = apc_erealloc(stack->data, sizeof(void*) * stack->capacity); } stack->data[stack->size++] = item; } -void* apc_stack_pop(apc_stack_t* stack) +void* +apc_stack_pop(apc_stack_t* stack) { assert(stack != NULL && stack->size > 0); return stack->data[--stack->size]; } -void* apc_stack_top(apc_stack_t* stack) +void* +apc_stack_top(apc_stack_t* stack) { assert(stack != NULL && stack->size > 0); - return stack->data[stack->size-1]; + return stack->data[stack->size - 1]; } -void* apc_stack_get(apc_stack_t* stack, int n) +void* +apc_stack_get(apc_stack_t* stack, int n) { assert(stack != NULL && stack->size > n); return stack->data[n]; } -int apc_stack_size(apc_stack_t* stack) +int +apc_stack_size(apc_stack_t* stack) { assert(stack != NULL); return stack->size; } - /* * Local variables: * tab-width: 4 diff --git a/apc_windows_srwlock_kernel.c b/apc_windows_srwlock_kernel.c index 42a69efa..ebb143b7 100644 --- a/apc_windows_srwlock_kernel.c +++ b/apc_windows_srwlock_kernel.c @@ -41,37 +41,38 @@ BYTE WINAPI RtlAcquireResourceExclusive(LPRTL_RWLOCK rwl, BYTE fWait); BYTE WINAPI RtlAcquireResourceShared(LPRTL_RWLOCK rwl, BYTE fWait); void WINAPI RtlReleaseResource(LPRTL_RWLOCK rwl); */ -typedef void (WINAPI *tRtlInitializeResource)(LPRTL_RWLOCK rwl); -typedef void (WINAPI *tRtlDeleteResource)(LPRTL_RWLOCK rwl); -typedef BYTE (WINAPI *tRtlAcquireResourceExclusive)(LPRTL_RWLOCK rwl, BYTE fWait); -typedef BYTE (WINAPI *tRtlAcquireResourceShared)(LPRTL_RWLOCK rwl, BYTE fWait); -typedef void (WINAPI *tRtlReleaseResource)(LPRTL_RWLOCK rwl); -typedef void (WINAPI *tRtlDumpResource)(LPRTL_RWLOCK rwl); +typedef void(WINAPI* tRtlInitializeResource)(LPRTL_RWLOCK rwl); +typedef void(WINAPI* tRtlDeleteResource)(LPRTL_RWLOCK rwl); +typedef BYTE(WINAPI* tRtlAcquireResourceExclusive)(LPRTL_RWLOCK rwl, BYTE fWait); +typedef BYTE(WINAPI* tRtlAcquireResourceShared)(LPRTL_RWLOCK rwl, BYTE fWait); +typedef void(WINAPI* tRtlReleaseResource)(LPRTL_RWLOCK rwl); +typedef void(WINAPI* tRtlDumpResource)(LPRTL_RWLOCK rwl); -tRtlInitializeResource pRtlInitializeResource = 0; -tRtlDeleteResource pRtlDeleteResource = 0; -tRtlAcquireResourceExclusive pRtlAcquireResourceExclusive = 0; -tRtlAcquireResourceShared pRtlAcquireResourceShared = 0; -tRtlReleaseResource pRtlReleaseResource = 0; -tRtlDumpResource pRtlDumpResource = 0; +tRtlInitializeResource pRtlInitializeResource = 0; +tRtlDeleteResource pRtlDeleteResource = 0; +tRtlAcquireResourceExclusive pRtlAcquireResourceExclusive = 0; +tRtlAcquireResourceShared pRtlAcquireResourceShared = 0; +tRtlReleaseResource pRtlReleaseResource = 0; +tRtlDumpResource pRtlDumpResource = 0; HINSTANCE ntdll; -void apc_windows_cs_status(apc_windows_cs_rwlock_t *lock ); -apc_windows_cs_rwlock_t *apc_windows_cs_create(apc_windows_cs_rwlock_t *lock) +void apc_windows_cs_status(apc_windows_cs_rwlock_t* lock); +apc_windows_cs_rwlock_t* +apc_windows_cs_create(apc_windows_cs_rwlock_t* lock) { ntdll = LoadLibrary("ntdll.dll"); if (ntdll == 0) { - return NULL; + return NULL; } - pRtlInitializeResource = (tRtlInitializeResource) GetProcAddress(ntdll, "RtlInitializeResource"); - pRtlDeleteResource = (tRtlDeleteResource) GetProcAddress(ntdll, "RtlDeleteResource"); + pRtlInitializeResource = (tRtlInitializeResource) GetProcAddress(ntdll, "RtlInitializeResource"); + pRtlDeleteResource = (tRtlDeleteResource) GetProcAddress(ntdll, "RtlDeleteResource"); pRtlAcquireResourceExclusive = (tRtlAcquireResourceExclusive) GetProcAddress(ntdll, "RtlAcquireResourceExclusive"); - pRtlAcquireResourceShared = (tRtlAcquireResourceShared) GetProcAddress(ntdll, "RtlAcquireResourceShared"); - pRtlReleaseResource = (tRtlReleaseResource) GetProcAddress(ntdll, "RtlReleaseResource"); - pRtlDumpResource = (tRtlReleaseResource) GetProcAddress(ntdll, "RtlDumpResource"); - if (pRtlInitializeResource == 0 || pRtlDeleteResource == 0 || pRtlAcquireResourceExclusive == 0 || + pRtlAcquireResourceShared = (tRtlAcquireResourceShared) GetProcAddress(ntdll, "RtlAcquireResourceShared"); + pRtlReleaseResource = (tRtlReleaseResource) GetProcAddress(ntdll, "RtlReleaseResource"); + pRtlDumpResource = (tRtlReleaseResource) GetProcAddress(ntdll, "RtlDumpResource"); + if (pRtlInitializeResource == 0 || pRtlDeleteResource == 0 || pRtlAcquireResourceExclusive == 0 || pRtlAcquireResourceShared == 0 || pRtlReleaseResource == 0 || pRtlDumpResource == 0) { return NULL; } @@ -79,43 +80,46 @@ apc_windows_cs_rwlock_t *apc_windows_cs_create(apc_windows_cs_rwlock_t *lock) return lock; } -void apc_windows_cs_destroy(apc_windows_cs_rwlock_t *lock) +void +apc_windows_cs_destroy(apc_windows_cs_rwlock_t* lock) { - __try - { + __try { pRtlDeleteResource(lock); - } - __except(GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ? - EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) - { + } __except (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ? EXCEPTION_EXECUTE_HANDLER + : EXCEPTION_CONTINUE_SEARCH) { /* Ignore exception (resource was freed during shutdown of another thread) */ } FreeLibrary(ntdll); return; } -void apc_windows_cs_lock(apc_windows_cs_rwlock_t *lock) +void +apc_windows_cs_lock(apc_windows_cs_rwlock_t* lock) { pRtlAcquireResourceExclusive(lock, 1); } -void apc_windows_cs_rdlock(apc_windows_cs_rwlock_t *lock) +void +apc_windows_cs_rdlock(apc_windows_cs_rwlock_t* lock) { pRtlAcquireResourceShared(lock, 1); } -void apc_windows_cs_unlock_rd(apc_windows_cs_rwlock_t *lock) +void +apc_windows_cs_unlock_rd(apc_windows_cs_rwlock_t* lock) { pRtlReleaseResource(lock); } -void apc_windows_cs_unlock_wr(apc_windows_cs_rwlock_t *lock) +void +apc_windows_cs_unlock_wr(apc_windows_cs_rwlock_t* lock) { pRtlReleaseResource(lock); } /* debugging purposes, output using trace msgs */ -void apc_windows_cs_status(apc_windows_cs_rwlock_t *lock) +void +apc_windows_cs_status(apc_windows_cs_rwlock_t* lock) { pRtlDumpResource(lock); return; diff --git a/apc_windows_srwlock_kernel.h b/apc_windows_srwlock_kernel.h index dce0210a..1613b20c 100644 --- a/apc_windows_srwlock_kernel.h +++ b/apc_windows_srwlock_kernel.h @@ -25,18 +25,18 @@ #ifdef APC_SRWLOCK_KERNEL typedef struct _RTL_RWLOCK { - RTL_CRITICAL_SECTION rtlCS; + RTL_CRITICAL_SECTION rtlCS; - HANDLE hSharedReleaseSemaphore; - UINT uSharedWaiters; + HANDLE hSharedReleaseSemaphore; + UINT uSharedWaiters; - HANDLE hExclusiveReleaseSemaphore; - UINT uExclusiveWaiters; + HANDLE hExclusiveReleaseSemaphore; + UINT uExclusiveWaiters; - INT iNumberActive; - HANDLE hOwningThreadId; - DWORD dwTimeoutBoost; - PVOID pDebugInfo; + INT iNumberActive; + HANDLE hOwningThreadId; + DWORD dwTimeoutBoost; + PVOID pDebugInfo; } RTL_RWLOCK, *LPRTL_RWLOCK; #define apc_windows_cs_rwlock_t RTL_RWLOCK @@ -51,15 +51,15 @@ struct apc_windows_cs_rwlock_t { DWORD reader_races_lost; }; -apc_windows_cs_rwlock_t *apc_windows_cs_create(apc_windows_cs_rwlock_t *lock); -void apc_windows_cs_destroy(apc_windows_cs_rwlock_t *lock); -void apc_windows_cs_lock(apc_windows_cs_rwlock_t *lock); -void apc_windows_cs_rdlock(apc_windows_cs_rwlock_t *lock); -void apc_windows_cs_unlock_rd(apc_windows_cs_rwlock_t *lock); -void apc_windows_cs_unlock_wr(apc_windows_cs_rwlock_t *lock); -# if NONBLOCKING_LOCK_AVAILABLE==1 /* Only in win7/2008 */ -zend_bool apc_pthreadrwlock_nonblocking_lock(apc_windows_cs_rwlock_t *lock); -# endif +apc_windows_cs_rwlock_t* apc_windows_cs_create(apc_windows_cs_rwlock_t* lock); +void apc_windows_cs_destroy(apc_windows_cs_rwlock_t* lock); +void apc_windows_cs_lock(apc_windows_cs_rwlock_t* lock); +void apc_windows_cs_rdlock(apc_windows_cs_rwlock_t* lock); +void apc_windows_cs_unlock_rd(apc_windows_cs_rwlock_t* lock); +void apc_windows_cs_unlock_wr(apc_windows_cs_rwlock_t* lock); +#if NONBLOCKING_LOCK_AVAILABLE == 1 /* Only in win7/2008 */ +zend_bool apc_pthreadrwlock_nonblocking_lock(apc_windows_cs_rwlock_t* lock); +#endif #endif #endif diff --git a/format.sh b/format.sh new file mode 100755 index 00000000..9fce9148 --- /dev/null +++ b/format.sh @@ -0,0 +1,2 @@ +#!/bin/sh +clang-format -i *.c *.h diff --git a/pgsql_s_lock.c b/pgsql_s_lock.c index 139c8215..62796099 100644 --- a/pgsql_s_lock.c +++ b/pgsql_s_lock.c @@ -60,18 +60,17 @@ /* #include "storage/s_lock.h" -- Removed for APC */ #include "pgsql_s_lock.h" -static int spins_per_delay = DEFAULT_SPINS_PER_DELAY; - +static int spins_per_delay = DEFAULT_SPINS_PER_DELAY; /* -- APC specific additions ------------------------------*/ -/* The following dependencies have been copied from - * other pgsql source files. The original locations +/* The following dependencies have been copied from + * other pgsql source files. The original locations * have been noted. */ /* -- from include/c.h -- */ #ifndef TRUE -#define TRUE 1 +#define TRUE 1 #endif #ifndef FALSE @@ -79,21 +78,20 @@ static int spins_per_delay = DEFAULT_SPINS_PER_DELAY; #endif /* -- from include/pg_config_manual.h -- */ -#define MAX_RANDOM_VALUE (0x7FFFFFFF) +#define MAX_RANDOM_VALUE (0x7FFFFFFF) /* * Max * Return the maximum of two numbers. */ -#define Max(x, y) ((x) > (y) ? (x) : (y)) +#define Max(x, y) ((x) > (y) ? (x) : (y)) /* -- from include/c.h -- */ /* * Min * Return the minimum of two numbers. */ -#define Min(x, y) ((x) < (y) ? (x) : (y)) - +#define Min(x, y) ((x) < (y) ? (x) : (y)) /* -- from backend/port/win32/signal.c -- */ /* @@ -108,160 +106,148 @@ static int spins_per_delay = DEFAULT_SPINS_PER_DELAY; void pg_usleep(long microsec) { - if (microsec > 0) - { + if (microsec > 0) { #ifndef WIN32 - struct timeval delay; + struct timeval delay; - delay.tv_sec = microsec / 1000000L; - delay.tv_usec = microsec % 1000000L; - (void) select(0, NULL, NULL, NULL, &delay); + delay.tv_sec = microsec / 1000000L; + delay.tv_usec = microsec % 1000000L; + (void) select(0, NULL, NULL, NULL, &delay); #else - SleepEx((microsec < 500 ? 1 : (microsec + 500) / 1000), FALSE); + SleepEx((microsec < 500 ? 1 : (microsec + 500) / 1000), FALSE); #endif - } + } } /* -- End APC specific additions ------------------------------*/ - /* * s_lock_stuck() - complain about a stuck spinlock */ static void -s_lock_stuck(volatile slock_t *lock, const char *file, int line) +s_lock_stuck(volatile slock_t* lock, const char* file, int line) { #if defined(S_LOCK_TEST) - fprintf(stderr, - "\nStuck spinlock (%p) detected at %s:%d.\n", - lock, file, line); - exit(1); + fprintf(stderr, "\nStuck spinlock (%p) detected at %s:%d.\n", lock, file, line); + exit(1); #else - /* -- Removed for APC - elog(PANIC, "stuck spinlock (%p) detected at %s:%d", - lock, file, line); - */ - apc_error("Stuck spinlock (%p) detected", lock); + /* -- Removed for APC + elog(PANIC, "stuck spinlock (%p) detected at %s:%d", + lock, file, line); + */ + apc_error("Stuck spinlock (%p) detected", lock); #endif } - /* * s_lock(lock) - platform-independent portion of waiting for a spinlock. */ void -s_lock(volatile slock_t *lock, const char *file, int line) +s_lock(volatile slock_t* lock, const char* file, int line) { - /* - * We loop tightly for awhile, then delay using pg_usleep() and try again. - * Preferably, "awhile" should be a small multiple of the maximum time we - * expect a spinlock to be held. 100 iterations seems about right as an - * initial guess. However, on a uniprocessor the loop is a waste of - * cycles, while in a multi-CPU scenario it's usually better to spin a bit - * longer than to call the kernel, so we try to adapt the spin loop count - * depending on whether we seem to be in a uniprocessor or multiprocessor. - * - * Note: you might think MIN_SPINS_PER_DELAY should be just 1, but you'd - * be wrong; there are platforms where that can result in a "stuck - * spinlock" failure. This has been seen particularly on Alphas; it seems - * that the first TAS after returning from kernel space will always fail - * on that hardware. - * - * Once we do decide to block, we use randomly increasing pg_usleep() - * delays. The first delay is 1 msec, then the delay randomly increases to - * about one second, after which we reset to 1 msec and start again. The - * idea here is that in the presence of heavy contention we need to - * increase the delay, else the spinlock holder may never get to run and - * release the lock. (Consider situation where spinlock holder has been - * nice'd down in priority by the scheduler --- it will not get scheduled - * until all would-be acquirers are sleeping, so if we always use a 1-msec - * sleep, there is a real possibility of starvation.) But we can't just - * clamp the delay to an upper bound, else it would take a long time to - * make a reasonable number of tries. - * - * We time out and declare error after NUM_DELAYS delays (thus, exactly - * that many tries). With the given settings, this will usually take 2 or - * so minutes. It seems better to fix the total number of tries (and thus - * the probability of unintended failure) than to fix the total time - * spent. - * - * The pg_usleep() delays are measured in milliseconds because 1 msec is a - * common resolution limit at the OS level for newer platforms. On older - * platforms the resolution limit is usually 10 msec, in which case the - * total delay before timeout will be a bit more. - */ +/* + * We loop tightly for awhile, then delay using pg_usleep() and try again. + * Preferably, "awhile" should be a small multiple of the maximum time we + * expect a spinlock to be held. 100 iterations seems about right as an + * initial guess. However, on a uniprocessor the loop is a waste of + * cycles, while in a multi-CPU scenario it's usually better to spin a bit + * longer than to call the kernel, so we try to adapt the spin loop count + * depending on whether we seem to be in a uniprocessor or multiprocessor. + * + * Note: you might think MIN_SPINS_PER_DELAY should be just 1, but you'd + * be wrong; there are platforms where that can result in a "stuck + * spinlock" failure. This has been seen particularly on Alphas; it seems + * that the first TAS after returning from kernel space will always fail + * on that hardware. + * + * Once we do decide to block, we use randomly increasing pg_usleep() + * delays. The first delay is 1 msec, then the delay randomly increases to + * about one second, after which we reset to 1 msec and start again. The + * idea here is that in the presence of heavy contention we need to + * increase the delay, else the spinlock holder may never get to run and + * release the lock. (Consider situation where spinlock holder has been + * nice'd down in priority by the scheduler --- it will not get scheduled + * until all would-be acquirers are sleeping, so if we always use a 1-msec + * sleep, there is a real possibility of starvation.) But we can't just + * clamp the delay to an upper bound, else it would take a long time to + * make a reasonable number of tries. + * + * We time out and declare error after NUM_DELAYS delays (thus, exactly + * that many tries). With the given settings, this will usually take 2 or + * so minutes. It seems better to fix the total number of tries (and thus + * the probability of unintended failure) than to fix the total time + * spent. + * + * The pg_usleep() delays are measured in milliseconds because 1 msec is a + * common resolution limit at the OS level for newer platforms. On older + * platforms the resolution limit is usually 10 msec, in which case the + * total delay before timeout will be a bit more. + */ #define MIN_SPINS_PER_DELAY 10 #define MAX_SPINS_PER_DELAY 1000 -#define NUM_DELAYS 1000 -#define MIN_DELAY_MSEC 1 -#define MAX_DELAY_MSEC 1000 - - int spins = 0; - int delays = 0; - int cur_delay = 0; - - while (TAS(lock)) - { - /* CPU-specific delay each time through the loop */ - SPIN_DELAY(); - - /* Block the process every spins_per_delay tries */ - if (++spins >= spins_per_delay) - { - if (++delays > NUM_DELAYS) - s_lock_stuck(lock, file, line); - - if (cur_delay == 0) /* first time to delay? */ - cur_delay = MIN_DELAY_MSEC; - - pg_usleep(cur_delay * 1000L); +#define NUM_DELAYS 1000 +#define MIN_DELAY_MSEC 1 +#define MAX_DELAY_MSEC 1000 -#if defined(S_LOCK_TEST) - fprintf(stdout, "*"); - fflush(stdout); -#endif + int spins = 0; + int delays = 0; + int cur_delay = 0; - /* increase delay by a random fraction between 1X and 2X */ - cur_delay += (int) (cur_delay * - ((double) rand() / (double) MAX_RANDOM_VALUE) + 0.5); - /* wrap back to minimum delay when max is exceeded */ - if (cur_delay > MAX_DELAY_MSEC) - cur_delay = MIN_DELAY_MSEC; + while (TAS(lock)) { + /* CPU-specific delay each time through the loop */ + SPIN_DELAY(); - spins = 0; - } - } + /* Block the process every spins_per_delay tries */ + if (++spins >= spins_per_delay) { + if (++delays > NUM_DELAYS) + s_lock_stuck(lock, file, line); - /* - * If we were able to acquire the lock without delaying, it's a good - * indication we are in a multiprocessor. If we had to delay, it's a sign - * (but not a sure thing) that we are in a uniprocessor. Hence, we - * decrement spins_per_delay slowly when we had to delay, and increase it - * rapidly when we didn't. It's expected that spins_per_delay will - * converge to the minimum value on a uniprocessor and to the maximum - * value on a multiprocessor. - * - * Note: spins_per_delay is local within our current process. We want to - * average these observations across multiple backends, since it's - * relatively rare for this function to even get entered, and so a single - * backend might not live long enough to converge on a good value. That - * is handled by the two routines below. - */ - if (cur_delay == 0) - { - /* we never had to delay */ - if (spins_per_delay < MAX_SPINS_PER_DELAY) - spins_per_delay = Min(spins_per_delay + 100, MAX_SPINS_PER_DELAY); - } - else - { - if (spins_per_delay > MIN_SPINS_PER_DELAY) - spins_per_delay = Max(spins_per_delay - 1, MIN_SPINS_PER_DELAY); - } -} + if (cur_delay == 0) /* first time to delay? */ + cur_delay = MIN_DELAY_MSEC; + + pg_usleep(cur_delay * 1000L); + +#if defined(S_LOCK_TEST) + fprintf(stdout, "*"); + fflush(stdout); +#endif + /* increase delay by a random fraction between 1X and 2X */ + cur_delay += (int) (cur_delay * ((double) rand() / (double) MAX_RANDOM_VALUE) + 0.5); + /* wrap back to minimum delay when max is exceeded */ + if (cur_delay > MAX_DELAY_MSEC) + cur_delay = MIN_DELAY_MSEC; + + spins = 0; + } + } + + /* + * If we were able to acquire the lock without delaying, it's a good + * indication we are in a multiprocessor. If we had to delay, it's a sign + * (but not a sure thing) that we are in a uniprocessor. Hence, we + * decrement spins_per_delay slowly when we had to delay, and increase it + * rapidly when we didn't. It's expected that spins_per_delay will + * converge to the minimum value on a uniprocessor and to the maximum + * value on a multiprocessor. + * + * Note: spins_per_delay is local within our current process. We want to + * average these observations across multiple backends, since it's + * relatively rare for this function to even get entered, and so a single + * backend might not live long enough to converge on a good value. That + * is handled by the two routines below. + */ + if (cur_delay == 0) { + /* we never had to delay */ + if (spins_per_delay < MAX_SPINS_PER_DELAY) + spins_per_delay = Min(spins_per_delay + 100, MAX_SPINS_PER_DELAY); + } else { + if (spins_per_delay > MIN_SPINS_PER_DELAY) + spins_per_delay = Max(spins_per_delay - 1, MIN_SPINS_PER_DELAY); + } +} -#if 0 /* -- APC doesn't use the set_spins_per_delay or update_spins_per_delay -- */ +#if 0 /* -- APC doesn't use the set_spins_per_delay or update_spins_per_delay -- */ /* * Set local copy of spins_per_delay during backend startup. * @@ -304,9 +290,7 @@ update_spins_per_delay(int shared_spins_per_delay) * because the definitions for these are split between this file and s_lock.h. */ - -#ifdef HAVE_SPINLOCKS /* skip spinlocks if requested */ - +#ifdef HAVE_SPINLOCKS /* skip spinlocks if requested */ #if defined(__GNUC__) @@ -314,7 +298,6 @@ update_spins_per_delay(int shared_spins_per_delay) * All the gcc flavors that are not inlined */ - /* * Note: all the if-tests here probably ought to be testing gcc version * rather than platform, but I don't have adequate info to know what to @@ -325,10 +308,10 @@ update_spins_per_delay(int shared_spins_per_delay) static void tas_dummy() { - __asm__ __volatile__( + __asm__ __volatile__( #if defined(__NetBSD__) && defined(__ELF__) -/* no underscore for label and % for registers */ - "\ + /* no underscore for label and % for registers */ + "\ .global tas \n\ tas: \n\ movel %sp@(0x4),%a0 \n\ @@ -340,7 +323,7 @@ _success: \n\ moveq #0,%d0 \n\ rts \n" #else - "\ + "\ .global _tas \n\ _tas: \n\ movel sp@(0x4),a0 \n\ @@ -351,41 +334,39 @@ _tas: \n\ _success: \n\ moveq #0,d0 \n\ rts \n" -#endif /* __NetBSD__ && __ELF__ */ - ); +#endif /* __NetBSD__ && __ELF__ */ + ); } -#endif /* __m68k__ && !__linux__ */ -#else /* not __GNUC__ */ +#endif /* __m68k__ && !__linux__ */ +#else /* not __GNUC__ */ /* * All non gcc */ - #if defined(sun3) -static void -tas_dummy() /* really means: extern int tas(slock_t - * *lock); */ +static void tas_dummy() /* really means: extern int tas(slock_t + * *lock); */ { - asm("LLA0:"); - asm(" .data"); - asm(" .text"); - asm("|#PROC# 04"); - asm(" .globl _tas"); - asm("_tas:"); - asm("|#PROLOGUE# 1"); - asm(" movel sp@(0x4),a0"); - asm(" tas a0@"); - asm(" beq LLA1"); - asm(" moveq #-128,d0"); - asm(" rts"); - asm("LLA1:"); - asm(" moveq #0,d0"); - asm(" rts"); - asm(" .data"); + asm("LLA0:"); + asm(" .data"); + asm(" .text"); + asm("|#PROC# 04"); + asm(" .globl _tas"); + asm("_tas:"); + asm("|#PROLOGUE# 1"); + asm(" movel sp@(0x4),a0"); + asm(" tas a0@"); + asm(" beq LLA1"); + asm(" moveq #-128,d0"); + asm(" rts"); + asm("LLA1:"); + asm(" moveq #0,d0"); + asm(" rts"); + asm(" .data"); } -#endif /* sun3 */ -#endif /* not __GNUC__ */ -#endif /* HAVE_SPINLOCKS */ +#endif /* sun3 */ +#endif /* not __GNUC__ */ +#endif /* HAVE_SPINLOCKS */ #endif /* APC_SPIN_LOCKS */ diff --git a/pgsql_s_lock.h b/pgsql_s_lock.h index 08b379b3..c7acb341 100644 --- a/pgsql_s_lock.h +++ b/pgsql_s_lock.h @@ -98,18 +98,16 @@ /** APC namespace protection ************************************************/ /* hack to protect against any possible runtime namespace collisions...*/ -#define pg_usleep apc_spin_pg_usleep -#define s_lock apc_spin_s_lock -#define spins_per_delay apc_spin_spins_per_delay +#define pg_usleep apc_spin_pg_usleep +#define s_lock apc_spin_s_lock +#define spins_per_delay apc_spin_spins_per_delay /****************************************************************************/ - /* #include "storage/pg_sema.h" -- Removed for APC */ #define HAVE_SPINLOCKS 1 /* -- Added for APC */ -#ifdef HAVE_SPINLOCKS /* skip spinlocks if requested */ - +#ifdef HAVE_SPINLOCKS /* skip spinlocks if requested */ #if defined(__GNUC__) || defined(__ICC) /************************************************************************* @@ -121,10 +119,10 @@ /*---------- * Standard gcc asm format (assuming "volatile slock_t *lock"): - __asm__ __volatile__( - " instruction \n" - " instruction \n" - " instruction \n" + __asm__ __volatile__( + " instruction \n" + " instruction \n" + " instruction \n" : "=r"(_res), "+m"(*lock) // return register, in/out lock value : "r"(lock) // lock pointer, in input register : "memory", "cc"); // show clobbered registers here @@ -140,8 +138,7 @@ *---------- */ - -#ifdef __i386__ /* 32-bit i386 */ +#ifdef __i386__ /* 32-bit i386 */ #define HAS_TEST_AND_SET typedef unsigned char slock_t; @@ -149,25 +146,25 @@ typedef unsigned char slock_t; #define TAS(lock) tas(lock) static __inline__ int -tas(volatile slock_t *lock) +tas(volatile slock_t* lock) { - register slock_t _res = 1; - - /* - * Use a non-locking test before asserting the bus lock. Note that the - * extra test appears to be a small loss on some x86 platforms and a small - * win on others; it's by no means clear that we should keep it. - */ - __asm__ __volatile__( - " cmpb $0,%1 \n" - " jne 1f \n" - " lock \n" - " xchgb %0,%1 \n" - "1: \n" -: "+q"(_res), "+m"(*lock) -: -: "memory", "cc"); - return (int) _res; + register slock_t _res = 1; + + /* + * Use a non-locking test before asserting the bus lock. Note that the + * extra test appears to be a small loss on some x86 platforms and a small + * win on others; it's by no means clear that we should keep it. + */ + __asm__ __volatile__( + " cmpb $0,%1 \n" + " jne 1f \n" + " lock \n" + " xchgb %0,%1 \n" + "1: \n" + : "+q"(_res), "+m"(*lock) + : + : "memory", "cc"); + return (int) _res; } #define SPIN_DELAY() spin_delay() @@ -175,37 +172,35 @@ tas(volatile slock_t *lock) static __inline__ void spin_delay(void) { - /* - * This sequence is equivalent to the PAUSE instruction ("rep" is - * ignored by old IA32 processors if the following instruction is - * not a string operation); the IA-32 Architecture Software - * Developer's Manual, Vol. 3, Section 7.7.2 describes why using - * PAUSE in the inner loop of a spin lock is necessary for good - * performance: - * - * The PAUSE instruction improves the performance of IA-32 - * processors supporting Hyper-Threading Technology when - * executing spin-wait loops and other routines where one - * thread is accessing a shared lock or semaphore in a tight - * polling loop. When executing a spin-wait loop, the - * processor can suffer a severe performance penalty when - * exiting the loop because it detects a possible memory order - * violation and flushes the core processor's pipeline. The - * PAUSE instruction provides a hint to the processor that the - * code sequence is a spin-wait loop. The processor uses this - * hint to avoid the memory order violation and prevent the - * pipeline flush. In addition, the PAUSE instruction - * de-pipelines the spin-wait loop to prevent it from - * consuming execution resources excessively. - */ - __asm__ __volatile__( - " rep; nop \n"); + /* + * This sequence is equivalent to the PAUSE instruction ("rep" is + * ignored by old IA32 processors if the following instruction is + * not a string operation); the IA-32 Architecture Software + * Developer's Manual, Vol. 3, Section 7.7.2 describes why using + * PAUSE in the inner loop of a spin lock is necessary for good + * performance: + * + * The PAUSE instruction improves the performance of IA-32 + * processors supporting Hyper-Threading Technology when + * executing spin-wait loops and other routines where one + * thread is accessing a shared lock or semaphore in a tight + * polling loop. When executing a spin-wait loop, the + * processor can suffer a severe performance penalty when + * exiting the loop because it detects a possible memory order + * violation and flushes the core processor's pipeline. The + * PAUSE instruction provides a hint to the processor that the + * code sequence is a spin-wait loop. The processor uses this + * hint to avoid the memory order violation and prevent the + * pipeline flush. In addition, the PAUSE instruction + * de-pipelines the spin-wait loop to prevent it from + * consuming execution resources excessively. + */ + __asm__ __volatile__(" rep; nop \n"); } -#endif /* __i386__ */ +#endif /* __i386__ */ - -#ifdef __x86_64__ /* AMD Opteron, Intel EM64T */ +#ifdef __x86_64__ /* AMD Opteron, Intel EM64T */ #define HAS_TEST_AND_SET typedef unsigned char slock_t; @@ -213,22 +208,22 @@ typedef unsigned char slock_t; #define TAS(lock) tas(lock) static __inline__ int -tas(volatile slock_t *lock) +tas(volatile slock_t* lock) { - register slock_t _res = 1; - - /* - * On Opteron, using a non-locking test before the locking instruction - * is a huge loss. On EM64T, it appears to be a wash or small loss, - * so we needn't bother to try to distinguish the sub-architectures. - */ - __asm__ __volatile__( - " lock \n" - " xchgb %0,%1 \n" -: "+q"(_res), "+m"(*lock) -: -: "memory", "cc"); - return (int) _res; + register slock_t _res = 1; + + /* + * On Opteron, using a non-locking test before the locking instruction + * is a huge loss. On EM64T, it appears to be a wash or small loss, + * so we needn't bother to try to distinguish the sub-architectures. + */ + __asm__ __volatile__( + " lock \n" + " xchgb %0,%1 \n" + : "+q"(_res), "+m"(*lock) + : + : "memory", "cc"); + return (int) _res; } #define SPIN_DELAY() spin_delay() @@ -236,18 +231,16 @@ tas(volatile slock_t *lock) static __inline__ void spin_delay(void) { - /* - * Adding a PAUSE in the spin delay loop is demonstrably a no-op on - * Opteron, but it may be of some use on EM64T, so we keep it. - */ - __asm__ __volatile__( - " rep; nop \n"); + /* + * Adding a PAUSE in the spin delay loop is demonstrably a no-op on + * Opteron, but it may be of some use on EM64T, so we keep it. + */ + __asm__ __volatile__(" rep; nop \n"); } -#endif /* __x86_64__ */ - +#endif /* __x86_64__ */ -#if defined(__ia64__) || defined(__ia64) /* Intel Itanium */ +#if defined(__ia64__) || defined(__ia64) /* Intel Itanium */ #define HAS_TEST_AND_SET typedef unsigned int slock_t; @@ -257,33 +250,28 @@ typedef unsigned int slock_t; #ifndef __INTEL_COMPILER static __inline__ int -tas(volatile slock_t *lock) +tas(volatile slock_t* lock) { - long int ret; - - __asm__ __volatile__( - " xchg4 %0=%1,%2 \n" -: "=r"(ret), "+m"(*lock) -: "r"(1) -: "memory"); - return (int) ret; + long int ret; + + __asm__ __volatile__(" xchg4 %0=%1,%2 \n" : "=r"(ret), "+m"(*lock) : "r"(1) : "memory"); + return (int) ret; } #else /* __INTEL_COMPILER */ static __inline__ int -tas(volatile slock_t *lock) +tas(volatile slock_t* lock) { - int ret; + int ret; - ret = _InterlockedExchange(lock,1); /* this is a xchg asm macro */ + ret = _InterlockedExchange(lock, 1); /* this is a xchg asm macro */ - return ret; + return ret; } #endif /* __INTEL_COMPILER */ -#endif /* __ia64__ || __ia64 */ - +#endif /* __ia64__ || __ia64 */ #if defined(__arm__) || defined(__arm) #define HAS_TEST_AND_SET @@ -293,20 +281,15 @@ typedef unsigned char slock_t; #define TAS(lock) tas(lock) static __inline__ int -tas(volatile slock_t *lock) +tas(volatile slock_t* lock) { - register slock_t _res = 1; - - __asm__ __volatile__( - " swpb %0, %0, [%2] \n" -: "+r"(_res), "+m"(*lock) -: "r"(lock) -: "memory"); - return (int) _res; -} + register slock_t _res = 1; -#endif /* __arm__ */ + __asm__ __volatile__(" swpb %0, %0, [%2] \n" : "+r"(_res), "+m"(*lock) : "r"(lock) : "memory"); + return (int) _res; +} +#endif /* __arm__ */ /* S/390 and S/390x Linux (32- and 64-bit zSeries) */ #if defined(__s390__) || defined(__s390x__) @@ -314,25 +297,20 @@ tas(volatile slock_t *lock) typedef unsigned int slock_t; -#define TAS(lock) tas(lock) +#define TAS(lock) tas(lock) static __inline__ int -tas(volatile slock_t *lock) +tas(volatile slock_t* lock) { - int _res = 0; - - __asm__ __volatile__( - " cs %0,%3,0(%2) \n" -: "+d"(_res), "+m"(*lock) -: "a"(lock), "d"(1) -: "memory", "cc"); - return _res; -} + int _res = 0; -#endif /* __s390__ || __s390x__ */ + __asm__ __volatile__(" cs %0,%3,0(%2) \n" : "+d"(_res), "+m"(*lock) : "a"(lock), "d"(1) : "memory", "cc"); + return _res; +} +#endif /* __s390__ || __s390x__ */ -#if defined(__sparc__) /* Sparc */ +#if defined(__sparc__) /* Sparc */ #define HAS_TEST_AND_SET typedef unsigned char slock_t; @@ -340,25 +318,20 @@ typedef unsigned char slock_t; #define TAS(lock) tas(lock) static __inline__ int -tas(volatile slock_t *lock) +tas(volatile slock_t* lock) { - register slock_t _res; - - /* - * See comment in /pg/backend/port/tas/solaris_sparc.s for why this - * uses "ldstub", and that file uses "cas". gcc currently generates - * sparcv7-targeted binaries, so "cas" use isn't possible. - */ - __asm__ __volatile__( - " ldstub [%2], %0 \n" -: "=r"(_res), "+m"(*lock) -: "r"(lock) -: "memory"); - return (int) _res; + register slock_t _res; + + /* + * See comment in /pg/backend/port/tas/solaris_sparc.s for why this + * uses "ldstub", and that file uses "cas". gcc currently generates + * sparcv7-targeted binaries, so "cas" use isn't possible. + */ + __asm__ __volatile__(" ldstub [%2], %0 \n" : "=r"(_res), "+m"(*lock) : "r"(lock) : "memory"); + return (int) _res; } -#endif /* __sparc__ */ - +#endif /* __sparc__ */ /* PowerPC */ #if defined(__ppc__) || defined(__powerpc__) || defined(__ppc64__) || defined(__powerpc64__) @@ -376,42 +349,40 @@ typedef unsigned int slock_t; * an isync is a sufficient synchronization barrier after a lwarx/stwcx loop. */ static __inline__ int -tas(volatile slock_t *lock) +tas(volatile slock_t* lock) { - slock_t _t; - int _res; - - __asm__ __volatile__( -" lwarx %0,0,%3 \n" -" cmpwi %0,0 \n" -" bne 1f \n" -" addi %0,%0,1 \n" -" stwcx. %0,0,%3 \n" -" beq 2f \n" -"1: li %1,1 \n" -" b 3f \n" -"2: \n" -" isync \n" -" li %1,0 \n" -"3: \n" - -: "=&r"(_t), "=r"(_res), "+m"(*lock) -: "r"(lock) -: "memory", "cc"); - return _res; + slock_t _t; + int _res; + + __asm__ __volatile__( + " lwarx %0,0,%3 \n" + " cmpwi %0,0 \n" + " bne 1f \n" + " addi %0,%0,1 \n" + " stwcx. %0,0,%3 \n" + " beq 2f \n" + "1: li %1,1 \n" + " b 3f \n" + "2: \n" + " isync \n" + " li %1,0 \n" + "3: \n" + + : "=&r"(_t), "=r"(_res), "+m"(*lock) + : "r"(lock) + : "memory", "cc"); + return _res; } /* PowerPC S_UNLOCK is almost standard but requires a "sync" instruction */ -#define S_UNLOCK(lock) \ -do \ -{ \ - __asm__ __volatile__ (" sync \n"); \ - *((volatile slock_t *) (lock)) = 0; \ -} while (0) +#define S_UNLOCK(lock) \ + do { \ + __asm__ __volatile__(" sync \n"); \ + *((volatile slock_t*) (lock)) = 0; \ + } while (0) #endif /* powerpc */ - /* Linux Motorola 68k */ #if (defined(__mc68000__) || defined(__m68k__)) && defined(__linux__) #define HAS_TEST_AND_SET @@ -421,22 +392,21 @@ typedef unsigned char slock_t; #define TAS(lock) tas(lock) static __inline__ int -tas(volatile slock_t *lock) +tas(volatile slock_t* lock) { - register int rv; - - __asm__ __volatile__( - " clrl %0 \n" - " tas %1 \n" - " sne %0 \n" -: "=d"(rv), "+m"(*lock) -: -: "memory", "cc"); - return rv; + register int rv; + + __asm__ __volatile__( + " clrl %0 \n" + " tas %1 \n" + " sne %0 \n" + : "=d"(rv), "+m"(*lock) + : + : "memory", "cc"); + return rv; } -#endif /* (__mc68000__ || __m68k__) && __linux__ */ - +#endif /* (__mc68000__ || __m68k__) && __linux__ */ /* * VAXen -- even multiprocessor ones @@ -450,25 +420,24 @@ typedef unsigned char slock_t; #define TAS(lock) tas(lock) static __inline__ int -tas(volatile slock_t *lock) +tas(volatile slock_t* lock) { - register int _res; - - __asm__ __volatile__( - " movl $1, %0 \n" - " bbssi $0, (%2), 1f \n" - " clrl %0 \n" - "1: \n" -: "=&r"(_res), "+m"(*lock) -: "r"(lock) -: "memory"); - return _res; + register int _res; + + __asm__ __volatile__( + " movl $1, %0 \n" + " bbssi $0, (%2), 1f \n" + " clrl %0 \n" + "1: \n" + : "=&r"(_res), "+m"(*lock) + : "r"(lock) + : "memory"); + return _res; } -#endif /* __vax__ */ +#endif /* __vax__ */ - -#if defined(__ns32k__) /* National Semiconductor 32K */ +#if defined(__ns32k__) /* National Semiconductor 32K */ #define HAS_TEST_AND_SET typedef unsigned char slock_t; @@ -476,69 +445,66 @@ typedef unsigned char slock_t; #define TAS(lock) tas(lock) static __inline__ int -tas(volatile slock_t *lock) +tas(volatile slock_t* lock) { - register int _res; - - __asm__ __volatile__( - " sbitb 0, %1 \n" - " sfsd %0 \n" -: "=r"(_res), "+m"(*lock) -: -: "memory"); - return _res; + register int _res; + + __asm__ __volatile__( + " sbitb 0, %1 \n" + " sfsd %0 \n" + : "=r"(_res), "+m"(*lock) + : + : "memory"); + return _res; } -#endif /* __ns32k__ */ - +#endif /* __ns32k__ */ -#if defined(__alpha) || defined(__alpha__) /* Alpha */ -/* - * Correct multi-processor locking methods are explained in section 5.5.3 - * of the Alpha AXP Architecture Handbook, which at this writing can be - * found at ftp://ftp.netbsd.org/pub/NetBSD/misc/dec-docs/index.html. - * For gcc we implement the handbook's code directly with inline assembler. - */ +#if defined(__alpha) || defined(__alpha__) /* Alpha */ + /* + * Correct multi-processor locking methods are explained in section 5.5.3 + * of the Alpha AXP Architecture Handbook, which at this writing can be + * found at ftp://ftp.netbsd.org/pub/NetBSD/misc/dec-docs/index.html. + * For gcc we implement the handbook's code directly with inline assembler. + */ #define HAS_TEST_AND_SET typedef unsigned long slock_t; -#define TAS(lock) tas(lock) +#define TAS(lock) tas(lock) static __inline__ int -tas(volatile slock_t *lock) +tas(volatile slock_t* lock) { - register slock_t _res; - - __asm__ __volatile__( - " ldq $0, %1 \n" - " bne $0, 2f \n" - " ldq_l %0, %1 \n" - " bne %0, 2f \n" - " mov 1, $0 \n" - " stq_c $0, %1 \n" - " beq $0, 2f \n" - " mb \n" - " br 3f \n" - "2: mov 1, %0 \n" - "3: \n" -: "=&r"(_res), "+m"(*lock) -: -: "memory", "0"); - return (int) _res; + register slock_t _res; + + __asm__ __volatile__( + " ldq $0, %1 \n" + " bne $0, 2f \n" + " ldq_l %0, %1 \n" + " bne %0, 2f \n" + " mov 1, $0 \n" + " stq_c $0, %1 \n" + " beq $0, 2f \n" + " mb \n" + " br 3f \n" + "2: mov 1, %0 \n" + "3: \n" + : "=&r"(_res), "+m"(*lock) + : + : "memory", "0"); + return (int) _res; } -#define S_UNLOCK(lock) \ -do \ -{\ - __asm__ __volatile__ (" mb \n"); \ - *((volatile slock_t *) (lock)) = 0; \ -} while (0) +#define S_UNLOCK(lock) \ + do { \ + __asm__ __volatile__(" mb \n"); \ + *((volatile slock_t*) (lock)) = 0; \ + } while (0) #endif /* __alpha || __alpha__ */ - -#if defined(__mips__) && !defined(__sgi) /* non-SGI MIPS */ +#if defined(__mips__) && !defined(__sgi) /* non-SGI MIPS */ /* Note: on SGI we use the OS' mutex ABI, see below */ /* Note: R10000 processors require a separate SYNC */ #define HAS_TEST_AND_SET @@ -548,60 +514,54 @@ typedef unsigned int slock_t; #define TAS(lock) tas(lock) static __inline__ int -tas(volatile slock_t *lock) +tas(volatile slock_t* lock) { - register volatile slock_t *_l = lock; - register int _res; - register int _tmp; - - __asm__ __volatile__( - " .set push \n" - " .set mips2 \n" - " .set noreorder \n" - " .set nomacro \n" - " ll %0, %2 \n" - " or %1, %0, 1 \n" - " sc %1, %2 \n" - " xori %1, 1 \n" - " or %0, %0, %1 \n" - " sync \n" - " .set pop " -: "=&r" (_res), "=&r" (_tmp), "+R" (*_l) -: -: "memory"); - return _res; + register volatile slock_t* _l = lock; + register int _res; + register int _tmp; + + __asm__ __volatile__( + " .set push \n" + " .set mips2 \n" + " .set noreorder \n" + " .set nomacro \n" + " ll %0, %2 \n" + " or %1, %0, 1 \n" + " sc %1, %2 \n" + " xori %1, 1 \n" + " or %0, %0, %1 \n" + " sync \n" + " .set pop " + : "=&r"(_res), "=&r"(_tmp), "+R"(*_l) + : + : "memory"); + return _res; } /* MIPS S_UNLOCK is almost standard but requires a "sync" instruction */ -#define S_UNLOCK(lock) \ -do \ -{ \ - __asm__ __volatile__( \ - " .set push \n" \ - " .set mips2 \n" \ - " .set noreorder \n" \ - " .set nomacro \n" \ - " sync \n" \ - " .set pop "); \ - *((volatile slock_t *) (lock)) = 0; \ -} while (0) +#define S_UNLOCK(lock) \ + do { \ + __asm__ __volatile__( \ + " .set push \n" \ + " .set mips2 \n" \ + " .set noreorder \n" \ + " .set nomacro \n" \ + " sync \n" \ + " .set pop "); \ + *((volatile slock_t*) (lock)) = 0; \ + } while (0) #endif /* __mips__ && !__sgi */ - /* These live in s_lock.c, but only for gcc */ - -#if defined(__m68k__) && !defined(__linux__) /* non-Linux Motorola 68k */ +#if defined(__m68k__) && !defined(__linux__) /* non-Linux Motorola 68k */ #define HAS_TEST_AND_SET typedef unsigned char slock_t; #endif - -#endif /* __GNUC__ */ - - +#endif /* __GNUC__ */ /* * --------------------------------------------------------------------- @@ -609,106 +569,91 @@ typedef unsigned char slock_t; * --------------------------------------------------------------------- */ -#if !defined(HAS_TEST_AND_SET) /* We didn't trigger above, let's try here */ +#if !defined(HAS_TEST_AND_SET) /* We didn't trigger above, let's try here */ - -#if defined(USE_UNIVEL_CC) /* Unixware compiler */ +#if defined(USE_UNIVEL_CC) /* Unixware compiler */ #define HAS_TEST_AND_SET typedef unsigned char slock_t; -#define TAS(lock) tas(lock) +#define TAS(lock) tas(lock) asm int -tas(volatile slock_t *s_lock) +tas(volatile slock_t* s_lock) { -/* UNIVEL wants %mem in column 1, so we don't pg_indent this file */ -%mem s_lock - pushl %ebx - movl s_lock, %ebx - movl $255, %eax - lock - xchgb %al, (%ebx) - popl %ebx + /* UNIVEL wants %mem in column 1, so we don't pg_indent this file */ + % mem s_lock pushl % ebx movl s_lock, % ebx movl $255, % eax lock xchgb % al, (% ebx) popl % ebx } -#endif /* defined(USE_UNIVEL_CC) */ - - -#if defined(__alpha) || defined(__alpha__) /* Tru64 Unix Alpha compiler */ -/* - * The Tru64 compiler doesn't support gcc-style inline asm, but it does - * have some builtin functions that accomplish much the same results. - * For simplicity, slock_t is defined as long (ie, quadword) on Alpha - * regardless of the compiler in use. LOCK_LONG and UNLOCK_LONG only - * operate on an int (ie, longword), but that's OK as long as we define - * S_INIT_LOCK to zero out the whole quadword. - */ +#endif /* defined(USE_UNIVEL_CC) */ + +#if defined(__alpha) || defined(__alpha__) /* Tru64 Unix Alpha compiler */ + /* + * The Tru64 compiler doesn't support gcc-style inline asm, but it does + * have some builtin functions that accomplish much the same results. + * For simplicity, slock_t is defined as long (ie, quadword) on Alpha + * regardless of the compiler in use. LOCK_LONG and UNLOCK_LONG only + * operate on an int (ie, longword), but that's OK as long as we define + * S_INIT_LOCK to zero out the whole quadword. + */ #define HAS_TEST_AND_SET typedef unsigned long slock_t; #include -#define S_INIT_LOCK(lock) (*(lock) = 0) -#define TAS(lock) (__LOCK_LONG_RETRY((lock), 1) == 0) -#define S_UNLOCK(lock) __UNLOCK_LONG(lock) - -#endif /* __alpha || __alpha__ */ +#define S_INIT_LOCK(lock) (*(lock) = 0) +#define TAS(lock) (__LOCK_LONG_RETRY((lock), 1) == 0) +#define S_UNLOCK(lock) __UNLOCK_LONG(lock) +#endif /* __alpha || __alpha__ */ -#if defined(__hppa) || defined(__hppa__) /* HP PA-RISC, GCC and HP compilers */ -/* - * HP's PA-RISC - * - * See src/backend/port/hpux/tas.c.template for details about LDCWX. Because - * LDCWX requires a 16-byte-aligned address, we declare slock_t as a 16-byte - * struct. The active word in the struct is whichever has the aligned address; - * the other three words just sit at -1. - * - * When using gcc, we can inline the required assembly code. - */ +#if defined(__hppa) || defined(__hppa__) /* HP PA-RISC, GCC and HP compilers */ + /* + * HP's PA-RISC + * + * See src/backend/port/hpux/tas.c.template for details about LDCWX. Because + * LDCWX requires a 16-byte-aligned address, we declare slock_t as a 16-byte + * struct. The active word in the struct is whichever has the aligned address; + * the other three words just sit at -1. + * + * When using gcc, we can inline the required assembly code. + */ #define HAS_TEST_AND_SET -typedef struct -{ - int sema[4]; +typedef struct { + int sema[4]; } slock_t; -#define TAS_ACTIVE_WORD(lock) ((volatile int *) (((long) (lock) + 15) & ~15)) +#define TAS_ACTIVE_WORD(lock) ((volatile int*) (((long) (lock) + 15) & ~15)) #if defined(__GNUC__) static __inline__ int -tas(volatile slock_t *lock) +tas(volatile slock_t* lock) { - volatile int *lockword = TAS_ACTIVE_WORD(lock); - register int lockval; - - __asm__ __volatile__( - " ldcwx 0(0,%2),%0 \n" -: "=r"(lockval), "+m"(*lockword) -: "r"(lockword) -: "memory"); - return (lockval == 0); + volatile int* lockword = TAS_ACTIVE_WORD(lock); + register int lockval; + + __asm__ __volatile__(" ldcwx 0(0,%2),%0 \n" : "=r"(lockval), "+m"(*lockword) : "r"(lockword) : "memory"); + return (lockval == 0); } #endif /* __GNUC__ */ -#define S_UNLOCK(lock) (*TAS_ACTIVE_WORD(lock) = -1) - -#define S_INIT_LOCK(lock) \ - do { \ - volatile slock_t *lock_ = (lock); \ - lock_->sema[0] = -1; \ - lock_->sema[1] = -1; \ - lock_->sema[2] = -1; \ - lock_->sema[3] = -1; \ - } while (0) +#define S_UNLOCK(lock) (*TAS_ACTIVE_WORD(lock) = -1) -#define S_LOCK_FREE(lock) (*TAS_ACTIVE_WORD(lock) != 0) +#define S_INIT_LOCK(lock) \ + do { \ + volatile slock_t* lock_ = (lock); \ + lock_->sema[0] = -1; \ + lock_->sema[1] = -1; \ + lock_->sema[2] = -1; \ + lock_->sema[3] = -1; \ + } while (0) -#endif /* __hppa || __hppa__ */ +#define S_LOCK_FREE(lock) (*TAS_ACTIVE_WORD(lock) != 0) +#endif /* __hppa || __hppa__ */ #if defined(__hpux) && defined(__ia64) && !defined(__GNUC__) @@ -719,90 +664,83 @@ typedef unsigned int slock_t; #include #define TAS(lock) _Asm_xchg(_SZ_W, lock, 1, _LDHINT_NONE) -#endif /* HPUX on IA64, non gcc */ - - -#if defined(__sgi) /* SGI compiler */ -/* - * SGI IRIX 5 - * slock_t is defined as a unsigned long. We use the standard SGI - * mutex API. - * - * The following comment is left for historical reasons, but is probably - * not a good idea since the mutex ABI is supported. - * - * This stuff may be supplemented in the future with Masato Kataoka's MIPS-II - * assembly from his NECEWS SVR4 port, but we probably ought to retain this - * for the R3000 chips out there. - */ +#endif /* HPUX on IA64, non gcc */ + +#if defined(__sgi) /* SGI compiler */ + /* + * SGI IRIX 5 + * slock_t is defined as a unsigned long. We use the standard SGI + * mutex API. + * + * The following comment is left for historical reasons, but is probably + * not a good idea since the mutex ABI is supported. + * + * This stuff may be supplemented in the future with Masato Kataoka's MIPS-II + * assembly from his NECEWS SVR4 port, but we probably ought to retain this + * for the R3000 chips out there. + */ #define HAS_TEST_AND_SET typedef unsigned long slock_t; #include "mutex.h" -#define TAS(lock) (test_and_set(lock,1)) -#define S_UNLOCK(lock) (test_then_and(lock,0)) -#define S_INIT_LOCK(lock) (test_then_and(lock,0)) -#define S_LOCK_FREE(lock) (test_then_add(lock,0) == 0) -#endif /* __sgi */ - - -#if defined(sinix) /* Sinix */ -/* - * SINIX / Reliant UNIX - * slock_t is defined as a struct abilock_t, which has a single unsigned long - * member. (Basically same as SGI) - */ +#define TAS(lock) (test_and_set(lock, 1)) +#define S_UNLOCK(lock) (test_then_and(lock, 0)) +#define S_INIT_LOCK(lock) (test_then_and(lock, 0)) +#define S_LOCK_FREE(lock) (test_then_add(lock, 0) == 0) +#endif /* __sgi */ + +#if defined(sinix) /* Sinix */ + /* + * SINIX / Reliant UNIX + * slock_t is defined as a struct abilock_t, which has a single unsigned long + * member. (Basically same as SGI) + */ #define HAS_TEST_AND_SET #include "abi_mutex.h" typedef abilock_t slock_t; -#define TAS(lock) (!acquire_lock(lock)) -#define S_UNLOCK(lock) release_lock(lock) -#define S_INIT_LOCK(lock) init_lock(lock) -#define S_LOCK_FREE(lock) (stat_lock(lock) == UNLOCKED) -#endif /* sinix */ +#define TAS(lock) (!acquire_lock(lock)) +#define S_UNLOCK(lock) release_lock(lock) +#define S_INIT_LOCK(lock) init_lock(lock) +#define S_LOCK_FREE(lock) (stat_lock(lock) == UNLOCKED) +#endif /* sinix */ - -#if defined(_AIX) /* AIX */ -/* - * AIX (POWER) - */ +#if defined(_AIX) /* AIX */ + /* + * AIX (POWER) + */ #define HAS_TEST_AND_SET typedef unsigned int slock_t; -#define TAS(lock) _check_lock(lock, 0, 1) -#define S_UNLOCK(lock) _clear_lock(lock, 0) -#endif /* _AIX */ - +#define TAS(lock) _check_lock(lock, 0, 1) +#define S_UNLOCK(lock) _clear_lock(lock, 0) +#endif /* _AIX */ -#if defined (nextstep) /* Nextstep */ +#if defined(nextstep) /* Nextstep */ #define HAS_TEST_AND_SET typedef struct mutex slock_t; -#define APC_SLOCK_NONBLOCKING_LOCK_AVAILABLE 0 /* -- APC: non-blocking lock not available in this case -- */ +#define APC_SLOCK_NONBLOCKING_LOCK_AVAILABLE 0 /* -- APC: non-blocking lock not available in this case -- */ -#define S_LOCK(lock) mutex_lock(lock) -#define S_UNLOCK(lock) mutex_unlock(lock) -#define S_INIT_LOCK(lock) mutex_init(lock) +#define S_LOCK(lock) mutex_lock(lock) +#define S_UNLOCK(lock) mutex_unlock(lock) +#define S_INIT_LOCK(lock) mutex_init(lock) /* For Mach, we have to delve inside the entrails of `struct mutex'. Ick! */ -#define S_LOCK_FREE(alock) ((alock)->lock == 0) -#endif /* nextstep */ - +#define S_LOCK_FREE(alock) ((alock)->lock == 0) +#endif /* nextstep */ /* These are in s_lock.c */ - -#if defined(sun3) /* Sun3 */ +#if defined(sun3) /* Sun3 */ #define HAS_TEST_AND_SET typedef unsigned char slock_t; #endif - #if defined(__sun) && (defined(__i386) || defined(__x86_64__) || defined(__sparc__) || defined(__sparc)) #define HAS_TEST_AND_SET @@ -812,13 +750,11 @@ typedef unsigned int slock_t; typedef unsigned char slock_t; #endif -extern slock_t pg_atomic_cas(volatile slock_t *lock, slock_t with, - slock_t cmp); +extern slock_t pg_atomic_cas(volatile slock_t* lock, slock_t with, slock_t cmp); #define TAS(a) (pg_atomic_cas((a), 1, 0) != 0) #endif - #ifdef WIN32_ONLY_COMPILER typedef LONG slock_t; @@ -830,27 +766,25 @@ typedef LONG slock_t; static __forceinline void spin_delay(void) { - /* See comment for gcc code. Same code, MASM syntax */ - __asm rep nop; + /* See comment for gcc code. Same code, MASM syntax */ + __asm rep nop; } #endif - -#endif /* !defined(HAS_TEST_AND_SET) */ - +#endif /* !defined(HAS_TEST_AND_SET) */ /* Blow up if we didn't have any way to do spinlocks */ #ifndef HAS_TEST_AND_SET -/* -- APC: We have better options in APC than this, that should be specified explicitly so just fail out and notify the user -- */ +/* -- APC: We have better options in APC than this, that should be specified explicitly so just fail out and notify the + * user -- */ #error Spin locking is not available on your platform, please select another locking method (see ./configure --help). -/* #error PostgreSQL does not have native spinlock support on this platform. To continue the compilation, rerun configure using --disable-spinlocks. -However, performance will be poor. Please report this to pgsql-bugs@postgresql.org. */ +/* #error PostgreSQL does not have native spinlock support on this platform. To continue the compilation, rerun +configure using --disable-spinlocks. +However, performance will be poor. Please report this to pgsql-bugs@postgresql.org. */ #endif - -#else /* !HAVE_SPINLOCKS */ - +#else /* !HAVE_SPINLOCKS */ /* * Fake spinlock implementation using semaphores --- slow and prone @@ -872,8 +806,7 @@ extern int tas_sema(volatile slock_t *lock); #define TAS(lock) tas_sema(lock) */ -#endif /* HAVE_SPINLOCKS */ - +#endif /* HAVE_SPINLOCKS */ /* * Default Definitions - override these above as needed. @@ -882,48 +815,47 @@ extern int tas_sema(volatile slock_t *lock); #define APC_SLOCK_NONBLOCKING_LOCK_AVAILABLE 1 /* -- APC: Non-blocking lock available for this case -- */ #if !defined(S_LOCK) -#define S_LOCK(lock) \ - do { \ - if (TAS(lock)) \ - s_lock((lock), __FILE__, __LINE__); \ - } while (0) -#endif /* S_LOCK */ +#define S_LOCK(lock) \ + do { \ + if (TAS(lock)) \ + s_lock((lock), __FILE__, __LINE__); \ + } while (0) +#endif /* S_LOCK */ #if !defined(S_LOCK_FREE) -#define S_LOCK_FREE(lock) (*(lock) == 0) -#endif /* S_LOCK_FREE */ +#define S_LOCK_FREE(lock) (*(lock) == 0) +#endif /* S_LOCK_FREE */ #if !defined(S_UNLOCK) -#define S_UNLOCK(lock) (*((volatile slock_t *) (lock)) = 0) -#endif /* S_UNLOCK */ +#define S_UNLOCK(lock) (*((volatile slock_t*) (lock)) = 0) +#endif /* S_UNLOCK */ #if !defined(S_INIT_LOCK) -#define S_INIT_LOCK(lock) S_UNLOCK(lock) -#endif /* S_INIT_LOCK */ +#define S_INIT_LOCK(lock) S_UNLOCK(lock) +#endif /* S_INIT_LOCK */ #if !defined(SPIN_DELAY) -#define SPIN_DELAY() ((void) 0) -#endif /* SPIN_DELAY */ +#define SPIN_DELAY() ((void) 0) +#endif /* SPIN_DELAY */ #if !defined(TAS) -extern int tas(volatile slock_t *lock); /* in port/.../tas.s, or - * s_lock.c */ - -#define TAS(lock) tas(lock) -#endif /* TAS */ +extern int tas(volatile slock_t* lock); /* in port/.../tas.s, or + * s_lock.c */ +#define TAS(lock) tas(lock) +#endif /* TAS */ /* * Platform-independent out-of-line support routines */ -extern void s_lock(volatile slock_t *lock, const char *file, int line); +extern void s_lock(volatile slock_t* lock, const char* file, int line); /* Support for dynamic adjustment of spins_per_delay */ -#define DEFAULT_SPINS_PER_DELAY 100 +#define DEFAULT_SPINS_PER_DELAY 100 -#if 0 /* -- Removed from APC use -- */ +#if 0 /* -- Removed from APC use -- */ extern void set_spins_per_delay(int shared_spins_per_delay); extern int update_spins_per_delay(int shared_spins_per_delay); #endif -#endif /* S_LOCK_H */ +#endif /* S_LOCK_H */ diff --git a/php_apc.c b/php_apc.c index de817fee..b4df7dcd 100644 --- a/php_apc.c +++ b/php_apc.c @@ -29,7 +29,7 @@ /* $Id: php_apc.c 328290 2012-11-09 03:30:09Z laruence $ */ #ifdef HAVE_CONFIG_H -# include "config.h" +#include "config.h" #endif #include "apc_cache.h" @@ -81,16 +81,17 @@ apc_cache_t* apc_user_cache = NULL; apc_sma_api_extern(apc_sma); /* Global init functions */ -static void php_apc_init_globals(zend_apcu_globals* apcu_globals) +static void +php_apc_init_globals(zend_apcu_globals* apcu_globals) { - apcu_globals->initialized = 0; - apcu_globals->slam_defense = 1; - apcu_globals->smart = 0; - apcu_globals->preload_path = NULL; - apcu_globals->coredump_unmap = 0; + apcu_globals->initialized = 0; + apcu_globals->slam_defense = 1; + apcu_globals->smart = 0; + apcu_globals->preload_path = NULL; + apcu_globals->coredump_unmap = 0; apcu_globals->use_request_time = 1; - apcu_globals->serializer_name = NULL; - apcu_globals->recursion = 0; + apcu_globals->serializer_name = NULL; + apcu_globals->recursion = 0; } /* }}} */ @@ -99,7 +100,7 @@ static void php_apc_init_globals(zend_apcu_globals* apcu_globals) static PHP_INI_MH(OnUpdateShmSegments) /* {{{ */ { #if APC_MMAP - if (zend_atoi(new_value->val, new_value->len)!=1) { + if (zend_atoi(new_value->val, new_value->len) != 1) { php_error_docref(NULL, E_WARNING, "apc.shm_segments setting ignored in MMAP mode"); } APCG(shm_segments) = 1; @@ -120,8 +121,7 @@ static PHP_INI_MH(OnUpdateShmSize) /* {{{ */ if (s < Z_L(1048576)) { /* if it's less than 1Mb, they are probably using the old syntax */ - php_error_docref( - NULL, E_WARNING, "apc.shm_size now uses M/G suffixes, please update your ini files"); + php_error_docref(NULL, E_WARNING, "apc.shm_size now uses M/G suffixes, please update your ini files"); s = s * Z_L(1048576); } @@ -132,30 +132,40 @@ static PHP_INI_MH(OnUpdateShmSize) /* {{{ */ /* }}} */ PHP_INI_BEGIN() -STD_PHP_INI_BOOLEAN("apc.enabled", "1", PHP_INI_SYSTEM, OnUpdateBool, enabled, zend_apcu_globals, apcu_globals) -STD_PHP_INI_ENTRY("apc.shm_segments", "1", PHP_INI_SYSTEM, OnUpdateShmSegments, shm_segments, zend_apcu_globals, apcu_globals) -STD_PHP_INI_ENTRY("apc.shm_size", "32M", PHP_INI_SYSTEM, OnUpdateShmSize, shm_size, zend_apcu_globals, apcu_globals) -STD_PHP_INI_ENTRY("apc.entries_hint", "4096", PHP_INI_SYSTEM, OnUpdateLong, entries_hint, zend_apcu_globals, apcu_globals) -STD_PHP_INI_ENTRY("apc.gc_ttl", "3600", PHP_INI_SYSTEM, OnUpdateLong, gc_ttl, zend_apcu_globals, apcu_globals) -STD_PHP_INI_ENTRY("apc.ttl", "0", PHP_INI_SYSTEM, OnUpdateLong, ttl, zend_apcu_globals, apcu_globals) -STD_PHP_INI_ENTRY("apc.smart", "0", PHP_INI_SYSTEM, OnUpdateLong, smart, zend_apcu_globals, apcu_globals) +STD_PHP_INI_BOOLEAN("apc.enabled", "1", PHP_INI_SYSTEM, OnUpdateBool, enabled, zend_apcu_globals, apcu_globals) +STD_PHP_INI_ENTRY( + "apc.shm_segments", "1", PHP_INI_SYSTEM, OnUpdateShmSegments, shm_segments, zend_apcu_globals, apcu_globals) +STD_PHP_INI_ENTRY("apc.shm_size", "32M", PHP_INI_SYSTEM, OnUpdateShmSize, shm_size, zend_apcu_globals, apcu_globals) +STD_PHP_INI_ENTRY( + "apc.entries_hint", "4096", PHP_INI_SYSTEM, OnUpdateLong, entries_hint, zend_apcu_globals, apcu_globals) +STD_PHP_INI_ENTRY("apc.gc_ttl", "3600", PHP_INI_SYSTEM, OnUpdateLong, gc_ttl, zend_apcu_globals, apcu_globals) +STD_PHP_INI_ENTRY("apc.ttl", "0", PHP_INI_SYSTEM, OnUpdateLong, ttl, zend_apcu_globals, apcu_globals) +STD_PHP_INI_ENTRY("apc.smart", "0", PHP_INI_SYSTEM, OnUpdateLong, smart, zend_apcu_globals, apcu_globals) #if APC_MMAP -STD_PHP_INI_ENTRY("apc.mmap_file_mask", NULL, PHP_INI_SYSTEM, OnUpdateString, mmap_file_mask, zend_apcu_globals, apcu_globals) +STD_PHP_INI_ENTRY( + "apc.mmap_file_mask", NULL, PHP_INI_SYSTEM, OnUpdateString, mmap_file_mask, zend_apcu_globals, apcu_globals) #endif -STD_PHP_INI_BOOLEAN("apc.enable_cli", "0", PHP_INI_SYSTEM, OnUpdateBool, enable_cli, zend_apcu_globals, apcu_globals) -STD_PHP_INI_BOOLEAN("apc.slam_defense", "1", PHP_INI_SYSTEM, OnUpdateBool, slam_defense, zend_apcu_globals, apcu_globals) -STD_PHP_INI_ENTRY("apc.preload_path", (char*)NULL, PHP_INI_SYSTEM, OnUpdateString, preload_path, zend_apcu_globals, apcu_globals) -STD_PHP_INI_BOOLEAN("apc.coredump_unmap", "0", PHP_INI_SYSTEM, OnUpdateBool, coredump_unmap, zend_apcu_globals, apcu_globals) -STD_PHP_INI_BOOLEAN("apc.use_request_time", "1", PHP_INI_ALL, OnUpdateBool, use_request_time, zend_apcu_globals, apcu_globals) -STD_PHP_INI_ENTRY("apc.serializer", "php", PHP_INI_SYSTEM, OnUpdateStringUnempty, serializer_name, zend_apcu_globals, apcu_globals) -STD_PHP_INI_ENTRY("apc.writable", "/tmp", PHP_INI_SYSTEM, OnUpdateStringUnempty, writable, zend_apcu_globals, apcu_globals) +STD_PHP_INI_BOOLEAN("apc.enable_cli", "0", PHP_INI_SYSTEM, OnUpdateBool, enable_cli, zend_apcu_globals, apcu_globals) +STD_PHP_INI_BOOLEAN( + "apc.slam_defense", "1", PHP_INI_SYSTEM, OnUpdateBool, slam_defense, zend_apcu_globals, apcu_globals) +STD_PHP_INI_ENTRY( + "apc.preload_path", (char*) NULL, PHP_INI_SYSTEM, OnUpdateString, preload_path, zend_apcu_globals, apcu_globals) +STD_PHP_INI_BOOLEAN( + "apc.coredump_unmap", "0", PHP_INI_SYSTEM, OnUpdateBool, coredump_unmap, zend_apcu_globals, apcu_globals) +STD_PHP_INI_BOOLEAN( + "apc.use_request_time", "1", PHP_INI_ALL, OnUpdateBool, use_request_time, zend_apcu_globals, apcu_globals) +STD_PHP_INI_ENTRY( + "apc.serializer", "php", PHP_INI_SYSTEM, OnUpdateStringUnempty, serializer_name, zend_apcu_globals, apcu_globals) +STD_PHP_INI_ENTRY( + "apc.writable", "/tmp", PHP_INI_SYSTEM, OnUpdateStringUnempty, writable, zend_apcu_globals, apcu_globals) PHP_INI_END() /* }}} */ -zend_bool apc_is_enabled(void) +zend_bool +apc_is_enabled(void) { - return APCG(enabled); + return APCG(enabled); } /* {{{ PHP_MINFO_FUNCTION(apcu) */ @@ -177,19 +187,19 @@ static PHP_MINFO_FUNCTION(apcu) #endif if (APCG(enabled)) { - apc_serializer_t *serializer = NULL; - smart_str names = {0,}; + apc_serializer_t* serializer = NULL; + smart_str names = { + 0, + }; int i; - - for( i = 0, serializer = apc_get_serializers(); - serializer->name != NULL; - serializer++, i++) { + + for (i = 0, serializer = apc_get_serializers(); serializer->name != NULL; serializer++, i++) { if (i != 0) { - smart_str_appends(&names, ", "); - } + smart_str_appends(&names, ", "); + } smart_str_appends(&names, serializer->name); } - + if (names.s->val) { smart_str_0(&names); php_info_print_table_row(2, "Serialization Support", names.s->val); @@ -217,55 +227,52 @@ static PHP_MINIT_FUNCTION(apcu) REGISTER_INI_ENTRIES(); - /* locks initialized regardless of settings */ - apc_lock_init(); - + /* locks initialized regardless of settings */ + apc_lock_init(); + /* Disable APC in cli mode unless overridden by apc.enable_cli */ if (!APCG(enable_cli) && !strcmp(sapi_module.name, "cli")) { - APCG(enabled) = 0; + APCG(enabled) = 0; } - /* only run initialization if APC is enabled */ + /* only run initialization if APC is enabled */ if (APCG(enabled)) { if (!APCG(initialized)) { - /* ensure this runs only once */ - APCG(initialized) = 1; - - /* initialize shared memory allocator */ + /* ensure this runs only once */ + APCG(initialized) = 1; + +/* initialize shared memory allocator */ #if APC_MMAP - apc_sma.init(APCG(shm_segments), APCG(shm_size), APCG(mmap_file_mask)); + apc_sma.init(APCG(shm_segments), APCG(shm_size), APCG(mmap_file_mask)); #else - apc_sma.init(APCG(shm_segments), APCG(shm_size), NULL); + apc_sma.init(APCG(shm_segments), APCG(shm_size), NULL); #endif - REGISTER_LONG_CONSTANT(APC_SERIALIZER_CONSTANT, (zend_long)&_apc_register_serializer, CONST_PERSISTENT | CONST_CS); - - /* register default serializer */ - _apc_register_serializer( - "php", APC_SERIALIZER_NAME(php), APC_UNSERIALIZER_NAME(php), NULL); - - /* test out the constant function pointer */ - assert(apc_get_serializers()->name != NULL); - - /* create user cache */ - apc_user_cache = apc_cache_create( - &apc_sma, - apc_find_serializer(APCG(serializer_name)), - APCG(entries_hint), APCG(gc_ttl), APCG(ttl), APCG(smart), APCG(slam_defense)); - - /* initialize pooling */ - apc_pool_init(); - - /* preload data from path specified in configuration */ - if (APCG(preload_path)) { - apc_cache_preload( - apc_user_cache, APCG(preload_path)); - } + REGISTER_LONG_CONSTANT(APC_SERIALIZER_CONSTANT, (zend_long) &_apc_register_serializer, + CONST_PERSISTENT | CONST_CS); + + /* register default serializer */ + _apc_register_serializer("php", APC_SERIALIZER_NAME(php), APC_UNSERIALIZER_NAME(php), NULL); + + /* test out the constant function pointer */ + assert(apc_get_serializers()->name != NULL); + + /* create user cache */ + apc_user_cache = apc_cache_create(&apc_sma, apc_find_serializer(APCG(serializer_name)), APCG(entries_hint), + APCG(gc_ttl), APCG(ttl), APCG(smart), APCG(slam_defense)); + + /* initialize pooling */ + apc_pool_init(); + + /* preload data from path specified in configuration */ + if (APCG(preload_path)) { + apc_cache_preload(apc_user_cache, APCG(preload_path)); + } } } - /* initialize iterator object */ + /* initialize iterator object */ apc_iterator_init(module_number); return SUCCESS; @@ -275,21 +282,21 @@ static PHP_MINIT_FUNCTION(apcu) /* {{{ PHP_MSHUTDOWN_FUNCTION(apcu) */ static PHP_MSHUTDOWN_FUNCTION(apcu) { - /* locks shutdown regardless of settings */ - apc_lock_cleanup(); + /* locks shutdown regardless of settings */ + apc_lock_cleanup(); - /* only shut down if APC is enabled */ + /* only shut down if APC is enabled */ if (APCG(enabled)) { if (APCG(initialized)) { - /* destroy cache pointer */ - apc_cache_destroy(apc_user_cache); - /* cleanup shared memory */ - apc_sma.cleanup(); + /* destroy cache pointer */ + apc_cache_destroy(apc_user_cache); + /* cleanup shared memory */ + apc_sma.cleanup(); + + APCG(initialized) = 0; + } - APCG(initialized) = 0; - } - #if HAVE_SIGACTION apc_shutdown_signals(); #endif @@ -303,14 +310,14 @@ static PHP_MSHUTDOWN_FUNCTION(apcu) static PHP_RINIT_FUNCTION(apcu) { #if defined(ZTS) && defined(COMPILE_DL_APCU) - ZEND_TSRMLS_CACHE_UPDATE(); + ZEND_TSRMLS_CACHE_UPDATE(); #endif if (APCG(enabled)) { if (APCG(serializer_name)) { - /* Avoid race conditions between MINIT of apc and serializer exts like igbinary */ - apc_cache_serializer(apc_user_cache, APCG(serializer_name)); - } + /* Avoid race conditions between MINIT of apc and serializer exts like igbinary */ + apc_cache_serializer(apc_user_cache, APCG(serializer_name)); + } #if HAVE_SIGACTION apc_set_signals(); @@ -327,8 +334,7 @@ PHP_FUNCTION(apcu_clear_cache) return; } - apc_cache_clear( - apc_user_cache); + apc_cache_clear(apc_user_cache); RETURN_TRUE; } /* }}} */ @@ -346,7 +352,8 @@ PHP_FUNCTION(apcu_cache_info) info = apc_cache_info(apc_user_cache, limited); if (Z_TYPE(info) != IS_ARRAY) { - php_error_docref(NULL, E_WARNING, "No APC info available. Perhaps APC is not enabled? Check apc.enabled in your ini file"); + php_error_docref(NULL, E_WARNING, + "No APC info available. Perhaps APC is not enabled? Check apc.enabled in your ini file"); RETURN_FALSE; } @@ -357,12 +364,12 @@ PHP_FUNCTION(apcu_cache_info) /* {{{ */ PHP_FUNCTION(apcu_key_info) { - zend_string *key; - + zend_string* key; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "S", &key) == FAILURE) { return; } - + apc_cache_stat(apc_user_cache, key, return_value); } /* }}} */ @@ -387,8 +394,8 @@ PHP_FUNCTION(apcu_sma_info) array_init(return_value); add_assoc_long(return_value, "num_seg", info->num_seg); - add_assoc_double(return_value, "seg_size", (double)info->seg_size); - add_assoc_double(return_value, "avail_mem", (double)apc_sma.get_avail_mem()); + add_assoc_double(return_value, "seg_size", (double) info->seg_size); + add_assoc_double(return_value, "avail_mem", (double) apc_sma.get_avail_mem()); if (limited) { apc_sma.free_info(info); @@ -419,7 +426,8 @@ PHP_FUNCTION(apcu_sma_info) /* }}} */ /* {{{ php_apc_update */ -int php_apc_update(zend_string *key, apc_cache_updater_t updater, void* data) +int +php_apc_update(zend_string* key, apc_cache_updater_t updater, void* data) { if (!APCG(enabled)) { return 0; @@ -429,7 +437,7 @@ int php_apc_update(zend_string *key, apc_cache_updater_t updater, void* data) /* Avoid race conditions between MINIT of apc and serializer exts like igbinary */ apc_cache_serializer(apc_user_cache, APCG(serializer_name)); } - + if (!apc_cache_update(apc_user_cache, key, updater, data)) { return 0; } @@ -440,12 +448,13 @@ int php_apc_update(zend_string *key, apc_cache_updater_t updater, void* data) /* {{{ apc_store_helper(INTERNAL_FUNCTION_PARAMETERS, const zend_bool exclusive) */ -static void apc_store_helper(INTERNAL_FUNCTION_PARAMETERS, const zend_bool exclusive) +static void +apc_store_helper(INTERNAL_FUNCTION_PARAMETERS, const zend_bool exclusive) { - zval *key = NULL; - zval *val = NULL; + zval* key = NULL; + zval* val = NULL; zend_long ttl = 0L; - + if (zend_parse_parameters(ZEND_NUM_ARGS(), "z|zl", &key, &val, &ttl) == FAILURE) { return; } @@ -454,74 +463,77 @@ static void apc_store_helper(INTERNAL_FUNCTION_PARAMETERS, const zend_bool exclu /* cannot work without key */ RETURN_FALSE; } - - /* keep it tidy */ + + /* keep it tidy */ { - if (APCG(serializer_name)) { - /* Avoid race conditions between MINIT of apc and serializer exts like igbinary */ - apc_cache_serializer(apc_user_cache, APCG(serializer_name)); - } - - if (Z_TYPE_P(key) == IS_ARRAY) { - - zval *hentry; - zend_string *hkey; + if (APCG(serializer_name)) { + /* Avoid race conditions between MINIT of apc and serializer exts like igbinary */ + apc_cache_serializer(apc_user_cache, APCG(serializer_name)); + } + + if (Z_TYPE_P(key) == IS_ARRAY) { + + zval* hentry; + zend_string* hkey; zend_ulong hkey_idx; HashPosition hpos; HashTable* hash = Z_ARRVAL_P(key); /* note: only indicative of error */ - array_init(return_value); - zend_hash_internal_pointer_reset_ex(hash, &hpos); - while((hentry = zend_hash_get_current_data_ex(hash, &hpos))) { - if (zend_hash_get_current_key_ex(hash, &hkey, &hkey_idx, &hpos) == HASH_KEY_IS_STRING) { - if(!apc_cache_store(apc_user_cache, hkey, hentry, (uint32_t) ttl, exclusive)) { - add_assoc_long_ex(return_value, hkey->val, hkey->len, -1); /* -1: insertion error */ - } - } else { - add_index_long(return_value, hkey_idx, -1); /* -1: insertion error */ - } - zend_hash_move_forward_ex(hash, &hpos); - } - return; - } else { + array_init(return_value); + zend_hash_internal_pointer_reset_ex(hash, &hpos); + while ((hentry = zend_hash_get_current_data_ex(hash, &hpos))) { + if (zend_hash_get_current_key_ex(hash, &hkey, &hkey_idx, &hpos) == HASH_KEY_IS_STRING) { + if (!apc_cache_store(apc_user_cache, hkey, hentry, (uint32_t) ttl, exclusive)) { + add_assoc_long_ex(return_value, hkey->val, hkey->len, -1); /* -1: insertion error */ + } + } else { + add_index_long(return_value, hkey_idx, -1); /* -1: insertion error */ + } + zend_hash_move_forward_ex(hash, &hpos); + } + return; + } else { if (Z_TYPE_P(key) == IS_STRING) { - if (!val) { + if (!val) { /* nothing to store */ - RETURN_FALSE; - } + RETURN_FALSE; + } /* return true on success */ - if(apc_cache_store(apc_user_cache, Z_STR_P(key), val, (uint32_t) ttl, exclusive)) { - RETURN_TRUE; + if (apc_cache_store(apc_user_cache, Z_STR_P(key), val, (uint32_t) ttl, exclusive)) { + RETURN_TRUE; } - } else { + } else { apc_warning("apc_store expects key parameter to be a string or an array of key/value pairs."); - } + } } - } - - /* default */ + } + + /* default */ RETURN_FALSE; } /* }}} */ /* {{{ proto bool apcu_enabled(void) returns true when apcu is usable in the current environment */ -PHP_FUNCTION(apcu_enabled) { +PHP_FUNCTION(apcu_enabled) +{ RETURN_BOOL(APCG(enabled)); -} /* }}} */ +} /* }}} */ /* {{{ proto int apc_store(mixed key, mixed var [, long ttl ]) */ -PHP_FUNCTION(apcu_store) { +PHP_FUNCTION(apcu_store) +{ apc_store_helper(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0); } /* }}} */ /* {{{ proto int apc_add(mixed key, mixed var [, long ttl ]) */ -PHP_FUNCTION(apcu_add) { +PHP_FUNCTION(apcu_add) +{ apc_store_helper(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1); } /* }}} */ @@ -533,8 +545,10 @@ struct php_inc_updater_args { zval rval; }; -static zend_bool php_inc_updater(apc_cache_t* cache, apc_cache_entry_t* entry, void* data) { - struct php_inc_updater_args *args = (struct php_inc_updater_args*) data; +static zend_bool +php_inc_updater(apc_cache_t* cache, apc_cache_entry_t* entry, void* data) +{ + struct php_inc_updater_args* args = (struct php_inc_updater_args*) data; if (Z_TYPE(entry->val) == IS_LONG) { fast_long_add_function(&entry->val, &entry->val, &args->step); @@ -547,78 +561,82 @@ static zend_bool php_inc_updater(apc_cache_t* cache, apc_cache_entry_t* entry, v /* {{{ proto long apc_inc(string key [, long step [, bool& success]]) */ -PHP_FUNCTION(apcu_inc) { - zend_string *key; +PHP_FUNCTION(apcu_inc) +{ + zend_string* key; struct php_inc_updater_args args; zend_long step = 1; - zval *success = NULL; + zval* success = NULL; if (zend_parse_parameters(ZEND_NUM_ARGS(), "S|lz", &key, &step, &success) == FAILURE) { return; } - if (success) { - ZVAL_DEREF(success); - zval_ptr_dtor(success); - } + if (success) { + ZVAL_DEREF(success); + zval_ptr_dtor(success); + } - ZVAL_LONG(&args.step, step); + ZVAL_LONG(&args.step, step); if (php_apc_update(key, php_inc_updater, &args)) { if (success) { - ZVAL_TRUE(success); - } + ZVAL_TRUE(success); + } RETURN_ZVAL(&args.rval, 0, 0); } - + if (success) { - ZVAL_FALSE(success); - } - + ZVAL_FALSE(success); + } + RETURN_FALSE; } /* }}} */ /* {{{ proto long apc_dec(string key [, long step [, bool &success]]) */ -PHP_FUNCTION(apcu_dec) { - zend_string *key; +PHP_FUNCTION(apcu_dec) +{ + zend_string* key; struct php_inc_updater_args args; zend_long step = 1; - zval *success = NULL; + zval* success = NULL; if (zend_parse_parameters(ZEND_NUM_ARGS(), "S|lz", &key, &step, &success) == FAILURE) { return; } - if (success) { - ZVAL_DEREF(success); - zval_ptr_dtor(success); - } + if (success) { + ZVAL_DEREF(success); + zval_ptr_dtor(success); + } - ZVAL_LONG(&args.step, 0 - step); + ZVAL_LONG(&args.step, 0 - step); if (php_apc_update(key, php_inc_updater, &args)) { if (success) { - ZVAL_TRUE(success); - } + ZVAL_TRUE(success); + } RETURN_ZVAL(&args.rval, 0, 0); } - + if (success) { - ZVAL_FALSE(success); - } - + ZVAL_FALSE(success); + } + RETURN_FALSE; } /* }}} */ /* {{{ php_cas_updater */ -static zend_bool php_cas_updater(apc_cache_t* cache, apc_cache_entry_t* entry, void* data) { - zend_long* vals = ((zend_long*)data); - zend_long old = vals[0]; - zend_long new = vals[1]; +static zend_bool +php_cas_updater(apc_cache_t* cache, apc_cache_entry_t* entry, void* data) +{ + zend_long* vals = ((zend_long*) data); + zend_long old = vals[0]; + zend_long new = vals[1]; if (Z_TYPE(entry->val) == IS_LONG) { if (Z_LVAL(entry->val) == old) { @@ -633,8 +651,9 @@ static zend_bool php_cas_updater(apc_cache_t* cache, apc_cache_entry_t* entry, v /* {{{ proto int apc_cas(string key, int old, int new) */ -PHP_FUNCTION(apcu_cas) { - zend_string *key; +PHP_FUNCTION(apcu_cas) +{ + zend_string* key; zend_long vals[2]; if (zend_parse_parameters(ZEND_NUM_ARGS(), "Sll", &key, &vals[0], &vals[1]) == FAILURE) { @@ -642,8 +661,8 @@ PHP_FUNCTION(apcu_cas) { } if (php_apc_update(key, php_cas_updater, &vals)) { - RETURN_TRUE; - } + RETURN_TRUE; + } RETURN_FALSE; } @@ -651,14 +670,15 @@ PHP_FUNCTION(apcu_cas) { /* {{{ proto mixed apc_fetch(mixed key[, bool &success]) */ -PHP_FUNCTION(apcu_fetch) { - zval *key; - zval *success = NULL; +PHP_FUNCTION(apcu_fetch) +{ + zval* key; + zval* success = NULL; time_t t; if (!APCG(enabled)) { - RETURN_FALSE; - } + RETURN_FALSE; + } if (zend_parse_parameters(ZEND_NUM_ARGS(), "z|z", &key, &success) == FAILURE) { return; @@ -667,68 +687,70 @@ PHP_FUNCTION(apcu_fetch) { t = apc_time(); if (success) { - ZVAL_DEREF(success); + ZVAL_DEREF(success); zval_ptr_dtor(success); ZVAL_FALSE(success); } - if (Z_TYPE_P(key) != IS_STRING && Z_TYPE_P(key) != IS_ARRAY) { - convert_to_string(key); - } - - if (Z_TYPE_P(key) == IS_ARRAY || (Z_TYPE_P(key) == IS_STRING && Z_STRLEN_P(key) > 0)) { - if (Z_TYPE_P(key) == IS_STRING) { - if (apc_cache_fetch(apc_user_cache, Z_STR_P(key), t, &return_value)) { - if (success) { - ZVAL_TRUE(success); - } - } else { ZVAL_BOOL(return_value, 0); } - } else if (Z_TYPE_P(key) == IS_ARRAY) { - HashPosition hpos; - zval *hentry; - zval result; - - array_init(&result); - zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(key), &hpos); - while((hentry = zend_hash_get_current_data_ex(Z_ARRVAL_P(key), &hpos))) { - if (Z_TYPE_P(hentry) == IS_STRING) { - zval result_entry, - *iresult = &result_entry; - ZVAL_UNDEF(iresult); - - if (apc_cache_fetch(apc_user_cache, Z_STR_P(hentry), t, &iresult)) { - add_assoc_zval(&result, Z_STRVAL_P(hentry), &result_entry); - } - } else { - apc_warning("apc_fetch() expects a string or array of strings."); - } - - zend_hash_move_forward_ex(Z_ARRVAL_P(key), &hpos); - } - - RETVAL_ZVAL(&result, 0, 1); - - if (success) { - ZVAL_TRUE(success); - } - } - } else { - apc_warning("apc_fetch() expects a string or array of strings."); - RETURN_FALSE; - } + if (Z_TYPE_P(key) != IS_STRING && Z_TYPE_P(key) != IS_ARRAY) { + convert_to_string(key); + } + + if (Z_TYPE_P(key) == IS_ARRAY || (Z_TYPE_P(key) == IS_STRING && Z_STRLEN_P(key) > 0)) { + if (Z_TYPE_P(key) == IS_STRING) { + if (apc_cache_fetch(apc_user_cache, Z_STR_P(key), t, &return_value)) { + if (success) { + ZVAL_TRUE(success); + } + } else { + ZVAL_BOOL(return_value, 0); + } + } else if (Z_TYPE_P(key) == IS_ARRAY) { + HashPosition hpos; + zval* hentry; + zval result; + + array_init(&result); + zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(key), &hpos); + while ((hentry = zend_hash_get_current_data_ex(Z_ARRVAL_P(key), &hpos))) { + if (Z_TYPE_P(hentry) == IS_STRING) { + zval result_entry, *iresult = &result_entry; + ZVAL_UNDEF(iresult); + + if (apc_cache_fetch(apc_user_cache, Z_STR_P(hentry), t, &iresult)) { + add_assoc_zval(&result, Z_STRVAL_P(hentry), &result_entry); + } + } else { + apc_warning("apc_fetch() expects a string or array of strings."); + } + + zend_hash_move_forward_ex(Z_ARRVAL_P(key), &hpos); + } + + RETVAL_ZVAL(&result, 0, 1); + + if (success) { + ZVAL_TRUE(success); + } + } + } else { + apc_warning("apc_fetch() expects a string or array of strings."); + RETURN_FALSE; + } return; } /* }}} */ /* {{{ proto mixed apc_exists(mixed key) */ -PHP_FUNCTION(apcu_exists) { - zval *key; +PHP_FUNCTION(apcu_exists) +{ + zval* key; time_t t; if (!APCG(enabled)) { - RETURN_FALSE; - } + RETURN_FALSE; + } if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &key) == FAILURE) { return; @@ -742,34 +764,33 @@ PHP_FUNCTION(apcu_exists) { if (Z_TYPE_P(key) == IS_STRING) { if (Z_STRLEN_P(key)) { - if (apc_cache_exists(apc_user_cache, Z_STR_P(key), t)) { - RETURN_TRUE; - } else { - RETURN_FALSE; - } - } + if (apc_cache_exists(apc_user_cache, Z_STR_P(key), t)) { + RETURN_TRUE; + } else { + RETURN_FALSE; + } + } } else if (Z_TYPE_P(key) == IS_ARRAY) { - HashPosition hpos; - zval *hentry; + HashPosition hpos; + zval* hentry; - array_init(return_value); + array_init(return_value); zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(key), &hpos); while ((hentry = zend_hash_get_current_data_ex(Z_ARRVAL_P(key), &hpos))) { if (Z_TYPE_P(hentry) == IS_STRING) { - if (apc_cache_exists(apc_user_cache, Z_STR_P(hentry), t)) { - add_assoc_bool(return_value, Z_STRVAL_P(hentry), 1); - } + if (apc_cache_exists(apc_user_cache, Z_STR_P(hentry), t)) { + add_assoc_bool(return_value, Z_STRVAL_P(hentry), 1); + } } else { - apc_warning( - "apc_exists() expects a string or array of strings."); - } + apc_warning("apc_exists() expects a string or array of strings."); + } - /* don't set values we didn't find */ + /* don't set values we didn't find */ zend_hash_move_forward_ex(Z_ARRVAL_P(key), &hpos); } - return; + return; } else { apc_warning("apc_exists() expects a string or array of strings."); } @@ -780,12 +801,13 @@ PHP_FUNCTION(apcu_exists) { /* {{{ proto mixed apc_delete(mixed keys) */ -PHP_FUNCTION(apcu_delete) { - zval *keys; +PHP_FUNCTION(apcu_delete) +{ + zval* keys; if (!APCG(enabled)) { - RETURN_FALSE; - } + RETURN_FALSE; + } if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &keys) == FAILURE) { return; @@ -793,8 +815,8 @@ PHP_FUNCTION(apcu_delete) { if (Z_TYPE_P(keys) == IS_STRING) { if (!Z_STRLEN_P(keys)) { - RETURN_FALSE; - } + RETURN_FALSE; + } if (apc_cache_delete(apc_user_cache, Z_STR_P(keys))) { RETURN_TRUE; @@ -804,7 +826,7 @@ PHP_FUNCTION(apcu_delete) { } else if (Z_TYPE_P(keys) == IS_ARRAY) { HashPosition hpos; - zval *hentry; + zval* hentry; array_init(return_value); zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(keys), &hpos); @@ -832,54 +854,50 @@ PHP_FUNCTION(apcu_delete) { } } -PHP_FUNCTION(apcu_entry) { - zval *key = NULL; - zend_fcall_info fci = empty_fcall_info; - zend_fcall_info_cache fcc = empty_fcall_info_cache; - zend_long ttl = 0L; - zend_long now = apc_time(); - - if (zend_parse_parameters(ZEND_NUM_ARGS(), "zf|l", &key, &fci, &fcc, &ttl) != SUCCESS) { - return; - } - - apc_cache_entry(apc_user_cache, key, &fci, &fcc, ttl, now, return_value); +PHP_FUNCTION(apcu_entry) +{ + zval* key = NULL; + zend_fcall_info fci = empty_fcall_info; + zend_fcall_info_cache fcc = empty_fcall_info_cache; + zend_long ttl = 0L; + zend_long now = apc_time(); + + if (zend_parse_parameters(ZEND_NUM_ARGS(), "zf|l", &key, &fci, &fcc, &ttl) != SUCCESS) { + return; + } + + apc_cache_entry(apc_user_cache, key, &fci, &fcc, ttl, now, return_value); } /* }}} */ /* {{{ apcu_functions[] */ zend_function_entry apcu_functions[] = { - PHP_FE(apcu_cache_info, arginfo_apcu_cache_info) - PHP_FE(apcu_clear_cache, arginfo_apcu_clear_cache) - PHP_FE(apcu_sma_info, arginfo_apcu_sma_info) - PHP_FE(apcu_key_info, arginfo_apcu_key_info) - PHP_FE(apcu_enabled, arginfo_apcu_enabled) - PHP_FE(apcu_store, arginfo_apcu_store) - PHP_FE(apcu_fetch, arginfo_apcu_fetch) - PHP_FE(apcu_delete, arginfo_apcu_delete) - PHP_FE(apcu_add, arginfo_apcu_store) - PHP_FE(apcu_inc, arginfo_apcu_inc) - PHP_FE(apcu_dec, arginfo_apcu_inc) - PHP_FE(apcu_cas, arginfo_apcu_cas) - PHP_FE(apcu_exists, arginfo_apcu_exists) - PHP_FE(apcu_entry, arginfo_apcu_entry) + /* clang-format off */ + PHP_FE(apcu_cache_info, arginfo_apcu_cache_info) + PHP_FE(apcu_clear_cache, arginfo_apcu_clear_cache) + PHP_FE(apcu_sma_info, arginfo_apcu_sma_info) + PHP_FE(apcu_key_info, arginfo_apcu_key_info) + PHP_FE(apcu_enabled, arginfo_apcu_enabled) + PHP_FE(apcu_store, arginfo_apcu_store) + PHP_FE(apcu_fetch, arginfo_apcu_fetch) + PHP_FE(apcu_delete, arginfo_apcu_delete) + PHP_FE(apcu_add, arginfo_apcu_store) + PHP_FE(apcu_inc, arginfo_apcu_inc) + PHP_FE(apcu_dec, arginfo_apcu_inc) + PHP_FE(apcu_cas, arginfo_apcu_cas) + PHP_FE(apcu_exists, arginfo_apcu_exists) + PHP_FE(apcu_entry, arginfo_apcu_entry) PHP_FE_END + /* clang-format on */ }; /* }}} */ /* {{{ module definition structure */ zend_module_entry apcu_module_entry = { - STANDARD_MODULE_HEADER, - PHP_APCU_EXTNAME, - apcu_functions, - PHP_MINIT(apcu), - PHP_MSHUTDOWN(apcu), - PHP_RINIT(apcu), - NULL, - PHP_MINFO(apcu), - PHP_APCU_VERSION, - STANDARD_MODULE_PROPERTIES + STANDARD_MODULE_HEADER, PHP_APCU_EXTNAME, apcu_functions, PHP_MINIT(apcu), + PHP_MSHUTDOWN(apcu), PHP_RINIT(apcu), NULL, PHP_MINFO(apcu), + PHP_APCU_VERSION, STANDARD_MODULE_PROPERTIES }; /* }}} */