static int Fusionee_GetPacket( Fusionee *fusionee, size_t size, Packet **ret_packet ) { Packet *packet; FUSION_DEBUG( "%s( %p )\n", __FUNCTION__, fusionee ); if (size > FUSION_MAX_PACKET_SIZE) return -E2BIG; packet = (Packet*) direct_list_last( fusionee->packets.items ); D_MAGIC_ASSERT_IF( packet, Packet ); if (!packet || packet->size + size > FUSION_MAX_PACKET_SIZE) { if (packet) { packet->flush = true; fusion_core_wq_wake( fusion_core, &fusionee->wait_receive); } if (fusionee->free_packets.count) { packet = (Packet*) fusion_fifo_get( &fusionee->free_packets ); D_MAGIC_ASSERT( packet, Packet ); } else packet = Packet_New(); if (!packet) return -ENOMEM; D_ASSERT( packet->link.prev == NULL ); D_ASSERT( packet->link.next == NULL ); fusion_fifo_put( &fusionee->packets, &packet->link ); } D_MAGIC_ASSERT( packet, Packet ); *ret_packet = packet; return 0; }
static void Packet_Free( Packet *packet ) { MessageCallback *callback; FUSION_DEBUG( "%s( %p )\n", __FUNCTION__, packet ); D_MAGIC_ASSERT( packet, Packet ); D_ASSERT( packet->link.prev == NULL ); D_ASSERT( packet->link.next == NULL ); D_MAGIC_CLEAR( packet ); while ((callback = (MessageCallback *) fusion_fifo_get(&packet->callbacks)) != NULL) { D_MAGIC_ASSERT( packet, Packet ); fusion_core_free( fusion_core, callback ); } fusion_core_free( fusion_core, packet ); }
static int Packet_RunCallbacks( FusionDev *dev, Packet *packet ) { MessageCallback *callback; FUSION_DEBUG( "%s( %p )\n", __FUNCTION__, packet ); D_MAGIC_ASSERT( packet, Packet ); while ((callback = (MessageCallback *) fusion_fifo_get(&packet->callbacks)) != NULL) { D_MAGIC_ASSERT( packet, Packet ); if (callback->func_index) { D_ASSERT( callback->func_index < D_ARRAY_SIZE(fusion_message_callbacks) ); fusion_message_callbacks[callback->func_index]( dev, callback->msg_id, callback->ctx, callback->param ); } fusion_core_free( fusion_core, callback ); } return 0; }