static int Packet_AddCallback( Packet *packet, int msg_id, FusionMessageCallback func, void *ctx, int param ) { MessageCallback *callback; FUSION_DEBUG( "%s( %p )\n", __FUNCTION__, packet ); D_MAGIC_ASSERT( packet, Packet ); callback = fusion_core_malloc( fusion_core, sizeof(MessageCallback) ); if (!callback) return -ENOMEM; callback->msg_id = msg_id; callback->func_index = func; callback->ctx = ctx; callback->param = param; fusion_fifo_put( &packet->callbacks, &callback->link ); return 0; }
client_t::~client_t() { FUSION_DEBUG("destroy client=%d", cid_); if (registered_) { result_t e = md_unreg_client(cid_); FUSION_ASSERT(e == ERR_OK); } delete conn_; ::free((void*)address_); }
static int Packet_Write( Packet *packet, int type, int msg_id, int channel, const void *msg_data, int msg_size, const void *extra_data, int extra_size, bool from_user ) { size_t total = sizeof(FusionReadMessage) + msg_size + extra_size; size_t aligned = (total + 3) & ~3; FusionReadMessage *header = (FusionReadMessage *)( packet->buf + packet->size ); FUSION_DEBUG( "%s( %p, msg_id %d, channel %d, size %d, extra %d, total %zu )\n", __FUNCTION__, packet, msg_id, channel, msg_size, extra_size, total ); D_MAGIC_ASSERT( packet, Packet ); FUSION_ASSERT( packet->size + aligned <= FUSION_MAX_PACKET_SIZE ); header->msg_type = type; header->msg_id = msg_id; header->msg_channel = channel; header->msg_size = msg_size + extra_size; if (from_user) { if (copy_from_user( header + 1, msg_data, msg_size )) return -EFAULT; } else memcpy( header + 1, msg_data, msg_size ); if (extra_data && extra_size) { if (copy_from_user( (char*)(header + 1) + msg_size, extra_data, extra_size )) return -EFAULT; } while (total < aligned) packet->buf[packet->size + total++] = 0; packet->size += aligned; return 0; }
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 Fusionee_PutPacket( Fusionee *fusionee, Packet *packet ) { FUSION_DEBUG( "%s( %p )\n", __FUNCTION__, fusionee ); D_MAGIC_ASSERT( packet, Packet ); D_ASSERT( packet->link.prev == NULL ); D_ASSERT( packet->link.next == NULL ); if (fusionee->free_packets.count > 10) Packet_Free( packet ); else { packet->size = 0; packet->flush = false; fusion_fifo_reset( &packet->callbacks ); fusion_fifo_put( &fusionee->free_packets, &packet->link ); } }
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 bool Packet_Search( Packet *packet, FusionMessageType msg_type, int msg_id ) { char *buf = packet->buf; size_t pos = 0; FUSION_DEBUG( "%s( %p )\n", __FUNCTION__, packet ); D_MAGIC_ASSERT( packet, Packet ); while (pos < packet->size) { FusionReadMessage *header = (FusionReadMessage *) &buf[pos]; if (header->msg_type == msg_type && header->msg_id == msg_id) return true; pos += sizeof(FusionReadMessage) + ((header->msg_size + 3) & ~3); } return false; }
static Packet * Packet_New( void ) { Packet *packet; FUSION_DEBUG( "%s()\n", __FUNCTION__ ); packet = fusion_core_malloc( fusion_core, sizeof(Packet) ); if (!packet) return NULL; packet->link.magic = 0; packet->link.prev = NULL; packet->link.next = NULL; packet->size = 0; packet->flush = false; fusion_fifo_reset( &packet->callbacks ); D_MAGIC_SET( packet, Packet ); return 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; }