📄 channels.c
字号:
} } while (chan_err == DE_BUSY); if (chan_err == DE_OKAY) { LogInfo(LOG_CHANNEL, ( "resend msg: %d ok\n", thispacket)); } else { LogError(LOG_CHANNEL, ( "resend msg: packet %d FAILED ret code 0x%x\n", thispacket, chan_err)); } /* now wait for the write to complete */ LogInfo(LOG_CHANNEL, ( "resend msg: waiting for send to complete...\n")); while (chan_state[chanid].write_blocking) { Angel_Yield(); } LogInfo(LOG_CHANNEL, ( "resend msg: send complete\n")); INC(thispacket); j = i; Angel_EnterCriticalSection(); } Angel_LeaveCriticalSection(); return adp_translate_dev_error(chan_err);}/* * Function: angel_ChannelRead * Purpose: blocking read of a packet from a channel * * see channels.h for full description *//* callback for this routine */static void read_unblock_callback(DeviceID devid, ChannelID chanid, p_Buffer buffer, unsigned len, void *callback_data){ ChanError chan_error; ChanError *read_error = (ChanError *) callback_data; ASSERT(chanid < CI_NUM_CHANNELS, ("Channel ID %d invalid in callback\n", chanid)); ASSERT(chan_state[chanid].read_blocking == TRUE, ("Read not blocking in callback\n")); ASSERT(read_error != NULL, ("Nowhere to write error code in callback\n")); /* unregister the async read */ chan_error = angel_ChannelReadAsync(devid, chanid, NULL, NULL); ASSERT(chan_error == CE_OKAY, ("Error unregistering async read in callback\n")); LogInfo(LOG_CHANNEL, ("read_unblock_callback: channel %d buffer %d len %d\n", chanid, buffer, len)); *read_error = CE_OKAY; chan_state[chanid].read_buffer = buffer; chan_state[chanid].read_len = len; chan_state[chanid].read_blocking = FALSE;}#ifdef NEED_CHANNEL_READChanError angel_ChannelRead(DeviceID devid, ChannelID chanid, p_Buffer * buffer, unsigned *len){ ChanError chan_error; ChanError read_error = CE_PRIVATE; ASSERT(chanid < CI_NUM_CHANNELS, ("Bad channel ID %d\n", chanid)); /* Check that a read is not already in progress */ Angel_EnterCriticalSection(); if (chan_state[chanid].read_blocking) { Angel_LeaveCriticalSection(); LogWarning(LOG_CHANNEL, ( "ChannelRead: already busy on chan %d\n", chanid)); return CE_BUSY; } chan_state[chanid].read_blocking = TRUE; Angel_LeaveCriticalSection(); /* Register an async read */ chan_error = angel_ChannelReadAsync(devid, chanid, read_unblock_callback, (void *)&read_error); if (chan_error != CE_OKAY) { chan_state[chanid].read_blocking = FALSE; return chan_error; } /* now wait for the read to complete */ while (chan_state[chanid].read_blocking) { TRACE("crb"); Angel_Yield(); } /* get at the results of the async read */ if (read_error == CE_OKAY) { *buffer = chan_state[chanid].read_buffer; *len = chan_state[chanid].read_len; } if (read_error) LogWarning(LOG_CHANNEL, ( "ChannelRead: error code %d\n", read_error)); return read_error;}#endif /* def NEED_CHANNEL_READ *//* * Function: angel_ChannelReadAsync * Purpose: asynchronous read of a packet via a channel * * see channels.h for full details */ChanError angel_ChannelReadAsync(DeviceID devid, ChannelID chanid, ChanRx_CB_Fn callback, void *callback_data){ /* adjust the device id, if required */ if (devid == CH_DEFAULT_DEV) { devid = active_device; } ASSERT(devid < DI_NUM_DEVICES, ("Bad device ID %d\n", devid)); /* we can only read from the active device in this version */ ASSERT(devid == active_device, ("ReadAsync device %d not active device %d\n", devid, active_device)); ASSERT(chanid < CI_NUM_CHANNELS, ("Bad channel ID %d\n", chanid)); /* * we can only service one request per channel in this version, * OR unregister by specifying a NULL callback */ Angel_EnterCriticalSection(); /* start critical region */ if (chan_state[chanid].reader != NULL && callback != NULL) { Angel_LeaveCriticalSection(); LogWarning(LOG_CHANNEL, ( "ChannelReadAsync: already reader on chan %d\n", chanid)); return CE_BUSY; } /* record what we need to know later */ chan_state[chanid].reader = callback; chan_state[chanid].read_cb_data = callback_data; Angel_LeaveCriticalSection(); /* end critical region */ /* that's all we need to do */ return CE_OKAY;}/* * Function: angel_ChannelReadAll * Purpose: register an asynchronous read across all devices * * see channels.h for full details */ChanError angel_ChannelReadAll(ChannelID chanid, ChanRx_CB_Fn callback, void *callback_data){ ASSERT(chanid < CI_NUM_CHANNELS, ("Bad channel ID %d\n", chanid)); ASSERT(callback != NULL, ("No callback function in Read All\n")); if (read_all_callback != NULL || chan_state[chanid].reader != NULL) { LogWarning(LOG_CHANNEL, ( "ChannelReadAll: already reader on chan %d\n", chanid)); return CE_BUSY; } /* just register the info */ read_all_channel = chanid; read_all_callback = callback; read_all_cb_data = callback_data; return CE_OKAY;}/* * Function: angel_ChannelSendThenRead * Purpose: blocking read of a packet from a channel * * see channels.h for full description */ChanError angel_ChannelSendThenRead(DeviceID devid, ChannelID chanid, p_Buffer * buffer, unsigned *len){ ChanError chan_error; ChanError send_error = CE_PRIVATE; ChanError read_error = CE_PRIVATE;#if DEBUG == 1 unsigned int reason; unpack_message(BUFFERDATA(*buffer), "%w", &reason);#endif ASSERT(chanid < CI_NUM_CHANNELS, ("Bad channel ID %d\n", chanid)); LogInfo(LOG_CHANNEL, ( "angel_ChannelSendThenRead: chan %d buffer %p, len %d [reason: %s]\n", chanid, *buffer, *len, log_adpname(reason))); /* Check that nothing is already in progress */ Angel_EnterCriticalSection(); if (chan_state[chanid].read_blocking || chan_state[chanid].write_blocking) { Angel_LeaveCriticalSection(); LogWarning(LOG_CHANNEL, ("ChannelSendThenRead: already busy on chan %d\n", chanid)); angel_ChannelReleaseBuffer(*buffer); return CE_BUSY; } chan_state[chanid].read_blocking = TRUE; chan_state[chanid].write_blocking = TRUE; Angel_LeaveCriticalSection(); /* Register an async read */ chan_error = angel_ChannelReadAsync(devid, chanid, read_unblock_callback, (void *)&read_error); if (chan_error != CE_OKAY) { LogWarning(LOG_CHANNEL, ("ChannelSendThenRead: Can't register read " "callback for chan %d\n", chanid)); angel_ChannelReleaseBuffer(*buffer); chan_state[chanid].read_blocking = FALSE; chan_state[chanid].write_blocking = FALSE; return chan_error; } /* Then start an async write */ chan_error = angel_ChannelSendAsync(devid, chanid, *buffer, *len, write_unblock_callback, (void *)&send_error); if (chan_error != CE_OKAY) { ChanError unreg_error; LogWarning(LOG_CHANNEL, ("ChannelSendThenRead: Send failed, error %d " "for chan %d\n", chan_error, chanid)); unreg_error = angel_ChannelReadAsync(devid, chanid, NULL, NULL); if (unreg_error != 0) LogWarning(LOG_CHANNEL, ("ChannelSendThenRead: Can't unregister read " "callback for chan %d, error %d\n", chanid, unreg_error)); chan_state[chanid].read_blocking = FALSE; chan_state[chanid].write_blocking = FALSE; return chan_error; } /* Now wait for both to complete */ while (chan_state[chanid].write_blocking || chan_state[chanid].read_blocking) { if (!chan_state[chanid].read_blocking) LogWarning(LOG_CHANNEL, ( "read packet before write complete\n")); TRACE("csr"); Angel_Yield(); } /* get at the results of the async read */ if (read_error == CE_OKAY) { *buffer = chan_state[chanid].read_buffer; *len = chan_state[chanid].read_len;#if DEBUG == 1 unpack_message(BUFFERDATA(*buffer), "%w", &reason); LogInfo(LOG_CHANNEL, ( "angel_ChannelSendThenRead: Return buffer %p, len %d [reason: %s]\n", *buffer, *len, log_adpname(reason)));#endif } if (read_error) LogWarning(LOG_CHANNEL, ( "SendThenRead: read error code %d\n", read_error)); if (send_error) LogWarning(LOG_CHANNEL, ( "SendThenRead: write error code %d\n", send_error)); return (send_error ? send_error : read_error);}/* * Function: angel_ChannelSelectDevice * Purpose: select the device to be used for all channel comms * * see channels.h for full details */ChanError angel_ChannelSelectDevice(DeviceID device){ unsigned int i; ASSERT(device < DI_NUM_DEVICES, ("Bad device ID %d\n", device)); LogInfo(LOG_CHANNEL, ( "ChannelSelectDevice: %d\n", device)); if (device == active_device) return CE_OKAY; /* already correct */ /* first we must do an abort on any blocking reads or writes */ for (i = 0; i < CI_NUM_CHANNELS; ++i) { if (chan_state[i].read_blocking) { ChanError *read_error = (ChanError *) chan_state[i].read_cb_data; ASSERT(read_error != NULL, ("angel_ChannelSelectDevice: write_error NULL\n")); LogWarning(LOG_CHANNEL, ( "ABANDON read on channel %d\n", i)); *read_error = CE_ABANDONED; if (chan_state[i].read_buffer != NULL) angel_ChannelReleaseBuffer(chan_state[i].read_buffer); chan_state[i].reader = NULL; chan_state[i].read_blocking = FALSE; } if (chan_state[i].write_blocking) { ChanError *write_error = (ChanError *) chan_state[i].write_cb_data; ASSERT(write_error != NULL, ("angel_ChannelSelectDevice: write_error NULL\n")); LogWarning(LOG_CHANNEL, ( "ABANDON write on channel %d\n", i)); *write_error = CE_ABANDONED; chan_state[i].writer = NULL; chan_state[i].write_buff = NULL; chan_state[i].write_blocking = FALSE; } } active_device = device; return CE_OKAY;}/* * Function: angel_ChannelReadActiveDevice * Purpose: reads the device id of the currently active device * * see channels.h for full details */ChanError angel_ChannelReadActiveDevice(DeviceID * device){ *device = active_device; return CE_OKAY;}/* EOF channels.c */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -