struct packet_info *packet_info_pool_get(struct proto *p) { struct packet_info *info = NULL; pom_mutex_lock(&p->pkt_info_pool.lock); if (!p->pkt_info_pool.unused) { // Allocate new packet_info info = malloc(sizeof(struct packet_info)); if (!info) { pom_mutex_unlock(&p->pkt_info_pool.lock); pom_oom(sizeof(struct packet_info)); return NULL; } memset(info, 0, sizeof(struct packet_info)); struct proto_pkt_field *fields = p->info->pkt_fields; int i; for (i = 0; fields[i].name; i++); info->fields_value = malloc(sizeof(struct ptype*) * (i + 1)); memset(info->fields_value, 0, sizeof(struct ptype*) * (i + 1)); for (; i--; ){ info->fields_value[i] = ptype_alloc_from_type(fields[i].value_type); if (!info->fields_value[i]) { i++; for (; fields[i].name; i++) ptype_cleanup(info->fields_value[i]); free(info); pom_mutex_unlock(&p->pkt_info_pool.lock); return NULL; } } debug_info_pool("Allocated info %p for proto %s", info, p->info->name); } else { // Dequeue the packet_info from the unused pool info = p->pkt_info_pool.unused; p->pkt_info_pool.unused = info->pool_next; if (p->pkt_info_pool.unused) p->pkt_info_pool.unused->pool_prev = NULL; debug_info_pool("Used info %p for proto %s", info, p->info->name); } // Queue the packet_info in the used pool info->pool_prev = NULL; info->pool_next = p->pkt_info_pool.used; if (info->pool_next) info->pool_next->pool_prev = info; p->pkt_info_pool.used = info; pom_mutex_unlock(&p->pkt_info_pool.lock); return info; }
int packet_info_pool_release(struct packet_info_pool *pool, struct packet_info *info) { if (!pool || !info) return POM_ERR; pom_mutex_lock(&pool->lock); // Dequeue from used and queue to unused if (info->pool_prev) info->pool_prev->pool_next = info->pool_next; else pool->used = info->pool_next; if (info->pool_next) info->pool_next->pool_prev = info->pool_prev; info->pool_next = pool->unused; if (info->pool_next) info->pool_next->pool_prev = info; pool->unused = info; debug_info_pool("Released info %p", info); pom_mutex_unlock(&pool->lock); return POM_OK; }
struct packet_info *packet_info_pool_get(struct proto *p) { struct packet_info *info = NULL; struct packet_info **pool = &packet_info_pool[p->id]; if (*pool) { // We can reuse the old one info = *pool; *pool = (*pool)->next; debug_info_pool("Used info %p for proto %s", info, p->info->name); } else { // Allocate new packet_info info = malloc(sizeof(struct packet_info)); if (!info) { pom_oom(sizeof(struct packet_info)); return NULL; } memset(info, 0, sizeof(struct packet_info)); struct proto_pkt_field *fields = p->info->pkt_fields; int i; for (i = 0; fields[i].name; i++); info->fields_value = malloc(sizeof(struct ptype*) * (i + 1)); memset(info->fields_value, 0, sizeof(struct ptype*) * (i + 1)); for (; i--; ) { info->fields_value[i] = ptype_alloc_from_type(fields[i].value_type); if (!info->fields_value[i]) { i++; for (; fields[i].name; i++) ptype_cleanup(info->fields_value[i]); free(info); return NULL; } } debug_info_pool("Allocated info %p for proto %s", info, p->info->name); } return info; }