/* 构造一个或者一堆的Frame 。 //服务器端发往客户端的数据 不允许使用 mask */ void wsframe_make(automem_t * mem,enum wsFrameType opcode, int _mask, unsigned char * payload, size_t len) { struct wsFrameHeader * fh; uint8_t mask[4]; size_t i; srand((unsigned int)time(NULL)); automem_ensure_newspace(mem, len + 20); fh = (struct wsFrameHeader * )(&mem->pdata[mem->size]); fh->fin = 1; fh->opcode = opcode; fh->rsv13 = 0; fh->mask = 0; mem->size += 2; if (len < 126) { fh->plen = (uint8_t)len; } else if (len <= 0xFFFF) { uint16_t nlen = SWAP_U16(len); fh->plen = 126; automem_append_voidp(mem, &nlen, 2); } else { uint64_t nlen = SWAP_U64(len); fh->plen = 127; automem_append_voidp(mem, &nlen, sizeof(uint64_t)); } if (payload && len > 0){ if (_mask) { fh->mask = 1; mask[0] = rand() % 256; mask[1] = rand() % 256; mask[2] = rand() % 256; mask[3] = rand() % 256; automem_append_voidp(mem, mask, 4); for (i = 0; i < len; i++) { mem->pdata[mem->size++] = payload[0] ^ mask[i % 4]; } } else { automem_append_voidp(mem, payload, len); } } }
void wsparser_pushdata(wsparser_t * parser, unsigned char * data, uint32_t size, wsparser_onhandler handler, void * eParam) { unsigned char *p = data; uint32_t i; if (parser->buf.size > 0) { automem_append_voidp(&parser->buf, data, size); data = parser->buf.pdata; size = parser->buf.size; } while (parser->offset < size) { switch (parser->st) { case WS_STATE_OPCODE: if (size - parser->offset > 2) { struct wsFrameHeader * fh = (struct wsFrameHeader *)&data[parser->offset]; parser->fin = fh->fin; parser->mask = fh->mask; parser->opcode = fh->opcode==WS_CONTINUATION_FRAME? parser->opcode: fh->opcode; parser->offset += 2; parser->st = WS_STATE_PLEN; printf("OpCode = %d, Fin=%d\n", parser->opcode,parser->fin); switch (fh->plen) { case 126: parser->st = WS_STATE_PLEN; break; case 127: parser->st = WS_STATE_PLLEN; break; default: parser->len = fh->plen; parser->st = parser->mask ? WS_STATE_MASK : WS_STATE_PAYLOAD; break; } if (WS_PING_FRAME == parser->opcode) { handler(parser, NULL, eParam); } } break; case WS_STATE_PLEN: if (size - parser->offset < 2) goto wsparser_pushdata_final; parser->len = SWAP_U16(*(uint16_t *)&data[parser->offset]); parser->offset += 2; parser->st = parser->mask ? WS_STATE_MASK : WS_STATE_PAYLOAD; break; case WS_STATE_PLLEN: if (size - parser->offset < 8) goto wsparser_pushdata_final; parser->len = SWAP_U64(*(uint64_t *)&data[parser->offset]); #if defined(_DEBUG) printf("size = %lld", parser->len); #endif parser->offset += 8; parser->st = parser->mask ? WS_STATE_MASK : WS_STATE_PAYLOAD; break; case WS_STATE_MASK: if (size - parser->offset < 4) goto wsparser_pushdata_final; memcpy(parser->msk_bytes, &data[parser->offset], 4); parser->offset += 4; parser->st = WS_STATE_PAYLOAD; break; case WS_STATE_PAYLOAD: if (size - parser->offset < parser->len) goto wsparser_pushdata_final; //处理帧数据 if (parser->mask) { automem_t * m = &parser->payload; automem_ensure_newspace(m, parser->len); for (i = 0; i < parser->len; i++) { m->pdata[m->size++] = data[parser->offset+i] ^ parser->msk_bytes[i % 4]; } } if (parser->fin == 1) { wsFrame * f = malloc(sizeof(wsFrame)); f->len = parser->payload.size; f->opcode = parser->opcode; f->pdata = f->len > 0 ? parser->payload.pdata : NULL; handler(parser, f, eParam); if (f->len){ parser->payload.pdata = NULL; parser->payload.size = parser->payload.buffersize = 0; automem_init(&parser->payload, 2048); } } parser->offset += (uint32_t)parser->len; parser->st = WS_STATE_OPCODE; break; } } wsparser_pushdata_final: if (size > parser->offset) { if (data != parser->buf.pdata) { automem_append_voidp(&parser->buf, data + parser->offset, size - parser->offset);//将未用完的加入到 buf. parser->offset = 0; } } else if (size <= parser->offset) { if (data == parser->buf.pdata) { } if (parser->buf.buffersize > parser->maxsize) automem_clean(&parser->buf, parser->maxsize); else automem_reset(&parser->buf); parser->offset = 0; } return; }
int ht_resize_pes(clht_t* h, int is_increase, int by) { ticks s = getticks(); check_ht_status_steps = CLHT_STATUS_INVOK; clht_hashtable_t* ht_old = h->ht; if (TRYLOCK_ACQ(&h->resize_lock)) { return 0; } size_t num_buckets_new; if (is_increase == true) { /* num_buckets_new = CLHT_RATIO_DOUBLE * ht_old->num_buckets; */ num_buckets_new = by * ht_old->num_buckets; } else { #if CLHT_HELP_RESIZE == 1 ht_old->is_helper = 0; #endif num_buckets_new = ht_old->num_buckets / CLHT_RATIO_HALVE; } /* printf("// resizing: from %8zu to %8zu buckets\n", ht_old->num_buckets, num_buckets_new); */ clht_hashtable_t* ht_new = clht_hashtable_create(num_buckets_new); ht_new->version = ht_old->version + 1; #if CLHT_HELP_RESIZE == 1 ht_old->table_tmp = ht_new; int32_t b; for (b = 0; b < ht_old->num_buckets; b++) { bucket_t* bu_cur = ht_old->table + b; if (!bucket_cpy(bu_cur, ht_new)) /* reached a point where the helper is handling */ { break; } } if (is_increase && ht_old->is_helper != 1) /* there exist a helper */ { while (ht_old->helper_done != 1) { _mm_pause(); } } #else int32_t b; for (b = 0; b < ht_old->num_buckets; b++) { bucket_t* bu_cur = ht_old->table + b; bucket_cpy(bu_cur, ht_new); } #endif #if defined(DEBUG) /* if (clht_size(ht_old) != clht_size(ht_new)) */ /* { */ /* printf("**clht_size(ht_old) = %zu != clht_size(ht_new) = %zu\n", clht_size(ht_old), clht_size(ht_new)); */ /* } */ #endif ht_new->table_prev = ht_old; int ht_resize_again = 0; if (ht_new->num_expands >= ht_new->num_expands_threshold) { /* printf("--problem: have already %u expands\n", ht_new->num_expands); */ ht_resize_again = 1; /* ht_new->num_expands_threshold = ht_new->num_expands + 1; */ } SWAP_U64((uint64_t*) h, (uint64_t) ht_new); ht_old->table_new = ht_new; TRYLOCK_RLS(h->resize_lock); ticks e = getticks() - s; double mba = (ht_new->num_buckets * 64) / (1024.0 * 1024); printf("[RESIZE-%02d] to #bu %7zu = MB: %7.2f | took: %13llu ti = %8.6f s\n", clht_gc_get_id(), ht_new->num_buckets, mba, (unsigned long long) e, e / 2.1e9); #if CLHT_DO_GC == 1 clht_gc_collect(h); #else clht_gc_release(ht_old); #endif if (ht_resize_again) { ht_status(h, 1, 0); } return 1; }