// convertStringToC: Copy ML string to 'buf' of size 'buflen' void convertStringToC(String mlStr, char *buf, size_t buflen, uintptr_t exn) { size_t sz; char *p; sz = sizeStringDefine(mlStr); if ( sz > buflen-1) { raise_exn(exn); } for ( p = &(mlStr->data); *p != '\0'; ) { *buf++ = *p++; } *buf = '\0'; return; }
// ML: cache * String * String -> (int * string_ptr) int apsml_cacheSet (int resultPair, Region sAddr, cache * c, int keyValPair, request_data * rd) /*{{{ */ { // allocate new entry and key,value placeholders // ppCache(c, rd); String key1 = (String) elemRecordML (keyValPair, 0); String value1 = (String) elemRecordML (keyValPair, 1); time_t timeout = (time_t) elemRecordML (keyValPair, 2); char *value = &(value1->data); int valuesize = sizeStringDefine(value1); char *key = &(key1->data); int keysize = sizeStringDefine(key1); int size = sizeof (entry) + keysize + 1 + valuesize + 1; entry *newentry = (entry *) malloc (size); // ap_log_error (APLOG_MARK, LOG_DEBUG, 0, rd->server, // "apsml_cacheCreate: malloc 0x%x, length: %d, sizeof(entry): %d, keysize: %d, valuesize: %d, key: %s, val: %s", (unsigned long) newentry, size, sizeof(entry), keysize, valuesize, key, value); if (newentry == NULL) return 0; char *newkey = (char *) (newentry + 1); char *newvalue = newkey + (keysize + 1); // prepare entry by copy data to my space and set pointers strncpy (newkey, key, keysize); newkey[keysize] = 0; strncpy (newvalue, value, valuesize); newvalue[valuesize] = 0; newentry->key = newkey; // newentry->key.hash = charhashfunction (newkey); newentry->data = newvalue; newentry->size = keysize + valuesize + sizeof (entry) + 2; time_t ct = time (NULL); if (timeout && c->timeout) { newentry->timeout = MIN (timeout, c->timeout); } else if (timeout) { newentry->timeout = timeout; } else { newentry->timeout = c->timeout; } newentry->time = ct + newentry->timeout; // We are going in !!! (as we get a writes lock we have // complete control [no more locks]) apr_thread_rwlock_wrlock (c->rwlock); int tmpsize = c->htable->hashTableSize; entry *oldentry = NULL; // void **oldentry1 = (void **) &oldentry; // ap_log_error (APLOG_MARK, LOG_NOTICE, 0, rd->server, // "apsml_cacheSet: key %s, hash: %i", key, newentry->key.hash); if (entrytable_find (c->htable, newentry->key, &oldentry) == hash_DNE) { // No old entry with that key if ((newentry->timeout == -1 && cacheheap_heapinsert(c->heap, newentry, (time_t) 0) == heap_OUTOFMEM) || (newentry->timeout && newentry->timeout != (time_t) -1 && cacheheap_heapinsert(c->heap, newentry, newentry->time) == heap_OUTOFMEM)) { ap_log_error (APLOG_MARK, LOG_NOTICE, 0, rd->server, "apsml_cacheSet: pid %d, received heap_OUTOFMEM", rd->ctx->pid); free(newentry); newentry = 0; } if (newentry && entrytable_insert (c->htable, newentry->key, newentry) == hash_OUTOFMEM) { ap_log_error (APLOG_MARK, LOG_NOTICE, 0, rd->server, "apsml_cacheSet: pid %d, received hash_OUTOFMEM", rd->ctx->pid); free (newentry); newentry = 0; } // ppCache(c, rd); oldentry = 0; } else { // Old exists if ((newentry->timeout == (time_t) -1 && cacheheap_heapinsert(c->heap, newentry, (time_t) 0) == heap_OUTOFMEM) || (newentry->timeout && newentry->timeout != (time_t) -1 && cacheheap_heapinsert(c->heap, newentry, newentry->time) == heap_OUTOFMEM)) { ap_log_error (APLOG_MARK, LOG_NOTICE, 0, rd->server, "apsml_cacheSet: pid %d, received heap_OUTOFMEM", rd->ctx->pid); free(newentry); newentry = 0; } if (newentry && entrytable_update (c->htable, newentry->key, newentry) == hash_OUTOFMEM) { ap_log_error (APLOG_MARK, LOG_NOTICE, 0, rd->server, "apsml_cacheSet: pid %d, received hash_OUTOFMEM", rd->ctx->pid); free (newentry); newentry = 0; } } if (newentry) { c->size += newentry->size; c->size += (tmpsize - c->htable->hashTableSize) * sizeof (entrytable_hashelement_t); } // ppCache(c, rd); int too_old = 0; if (oldentry) { // Old entry needs removel // time_t t = (ct - oldentry->time) < 0 ? 0 : ct - oldentry->time; if (oldentry->timeout && ct > oldentry->time) { too_old = 1; second (resultPair) = 0; } else { second (resultPair) = (int) convertStringToML (sAddr, oldentry->data); } listremoveitem (c, oldentry, rd); } if (too_old) oldentry = 0; if (newentry) LINKEDLIST_INSERTUNDER (c->sentinel, newentry); // I think we are done now // ppCache(c, rd); entry *curentry; // ap_log_error(APLOG_MARK, LOG_NOTICE, 0, rd->server, // "apsml_cacheSet: size %d, maxsize = %d, ct: %d", c->size, c->maxsize, ct); while (cacheheap_heapminimal(c->heap, &curentry) != heap_UNDERFLOW) { if (curentry->time < ct) { cacheremoveitem(c, curentry, rd); } else break; } // ppCache(c, rd); if (c->maxsize != -1) { while (c->size > c->maxsize) { curentry = c->sentinel->up; if (curentry == c->sentinel) break; cacheremoveitem (c, curentry, rd); } } apr_thread_rwlock_unlock (c->rwlock); // ppCache(c, rd); if (oldentry && newentry) { first (resultPair) = 1; return resultPair; } second (resultPair) = 0; if (newentry) { first (resultPair) = 2; return resultPair; } first (resultPair) = 0; return resultPair; } /*}}} */
if ( charNrC >= 0 && charNrC <= 255 ) { return convertIntToML (charNrC); } raise_exn(exn); return 0; // never reached } String REG_POLY_FUN_HDR(concatStringML, Region rAddr, String str1, String str2) { String res; char *s, *p; size_t i, sz; debug(printf("[enter concatStringML (rAddr=%p,str1=%p,str2=%p)]\n", rAddr,str1,str2);) sz = sizeStringDefine(str1) + sizeStringDefine(str2); res = REG_POLY_CALL(allocString, rAddr, sz); p = &(res->data); s = &(str1->data); for ( i = 0; i < sizeStringDefine(str1); i++) { *p++ = *s++; } s = &(str2->data); for ( i = 0; i < sizeStringDefine(str2); i++) { *p++ = *s++; } *p = '\0'; /* printf("\nconcatStringML\n%s\n%s\n -> \n%s\n", &(str1->data), &(str2->data), &(res->data)); printf("length 1: %d, length 2: %d, length 3: %d\n", sizeStringDefine(str1), sizeStringDefine(str2), sizeStringDefine(res)); */