int main( void ) { stop_watchdog(); setup_finish_ports(); setup_clock(); setup_uart(); rf_init(sizeof(struct packet)); configure_timer_38k(); timer_38k_enable(1); configure_watchdog(); __enable_interrupt(); // Show battery voltage on start display_vcc(); // Setup RF channel setup_channel(); set_state(st_stopped); // Start/stop loop for (;;) { wait_start(); set_state(st_started); beep(SHORT_DELAY_TICKS); detect_finish(); set_state(st_stopped); report_finish(); } }
// reset by peer(client) CASE_TEST(channel, io_stream_tcp_reset_by_client) { atbus::channel::io_stream_channel svr, cli; atbus::channel::io_stream_init(&svr, NULL, NULL); atbus::channel::io_stream_init(&cli, NULL, NULL); svr.evt.callbacks[atbus::channel::io_stream_callback_evt_t::EN_FN_DISCONNECTED] = disconnected_callback_test_fn; int check_flag = g_check_flag = 0; int inited_fds = 0; inited_fds += setup_channel(svr, "ipv6://:::16387", NULL); CASE_EXPECT_EQ(1, g_check_flag); CASE_EXPECT_NE(NULL, svr.ev_loop); if (0 == inited_fds) { return; } inited_fds = 0; inited_fds += setup_channel(cli, NULL, "ipv4://127.0.0.1:16387"); inited_fds += setup_channel(cli, NULL, "dns://localhost:16387"); inited_fds += setup_channel(cli, NULL, "ipv6://::1:16387"); while (g_check_flag - check_flag < 2 * inited_fds + 1) { atbus::channel::io_stream_run(&svr, atbus::adapter::RUN_NOWAIT); atbus::channel::io_stream_run(&cli, atbus::adapter::RUN_NOWAIT); CASE_THREAD_SLEEP_MS(8); } CASE_EXPECT_NE(0, cli.conn_pool.size()); check_flag = g_check_flag; atbus::channel::io_stream_close(&cli); CASE_EXPECT_EQ(0, cli.conn_pool.size()); while (g_check_flag - check_flag < inited_fds) { atbus::channel::io_stream_run(&svr, atbus::adapter::RUN_NOWAIT); CASE_THREAD_SLEEP_MS(8); } CASE_EXPECT_EQ(1, svr.conn_pool.size()); atbus::channel::io_stream_close(&svr); CASE_EXPECT_EQ(0, svr.conn_pool.size()); }
bool sdma_channel_init(unsigned int channel, struct channel_descriptor *cd_p, struct buffer_descriptor *base_bd_p) { struct channel_control_block *ccb_p; if (channel == 0 || channel >= CH_NUM || cd_p == NULL || base_bd_p == NULL) return false; ccb_p = &ccb_array[channel]; /* If initialized already, should close first then init. */ if (ccb_p->status.opened_init != 0) return false; /* Initialize channel control block. */ ccb_p->curr_bd_ptr = base_bd_p; ccb_p->base_bd_ptr = base_bd_p; ccb_p->channel_desc = cd_p; ccb_p->status.error = 0; ccb_p->status.opened_init = 1; ccb_p->status.state_direction = 0; ccb_p->status.execute = 0; /* Finish any channel descriptor inits. */ cd_p->ccb_ptr = ccb_p; cd_p->is_setup = 0; /* Do an initial setup now. */ if (!setup_channel(ccb_p)) { logf("SDMA ch init failed: %d", channel); cd_p->ccb_ptr = NULL; memset(ccb_p, 0x00, sizeof (struct channel_control_block)); return false; } /* Enable interrupt if a callback is specified. */ if (cd_p->callback != NULL) bitset32(&sdma_enabled_ints, 1ul << channel); /* Minimum schedulable = 1 */ sdma_channel_set_priority(channel, 1); logf("SDMA ch initialized: %d", channel); return true; }
/*!************************************************************************************** @Function main @Return void @Description Main function invoked after Application launch. ******************************************************************************************/ int main(void) { int n=-1; pthread_t thread1; pthread_t thread2; /* Ensure the contents are erased and file is created if doesn't exist*/ FILE *fd_instance = fopen( INSTANCEID_FIFO_NAME, "w"); fprintf(fd_instance,"%d",-1); fclose(fd_instance); printf("Initializing egl..\n\n"); if( 0 == initApplication()) { printf("EGL init failed"); return 0; } initView(); /* Launch user and pipe control threads */ n = pthread_create(&thread1, NULL, pipe_ctrl_thread, NULL); n = pthread_create(&thread2, NULL, user_ctrl_thread, NULL); while(1) { if(id != -1) setup_channel(); /* If any of the bc_cat devices are alive render */ if( (dev_fd0 != -1) || (dev_fd1 != -1) || (dev_fd2 != -1) || (dev_fd3 != -1) ) { render_thread(dev_fd0,0); render_thread(dev_fd1,1); render_thread(dev_fd2,2); render_thread(dev_fd3,3); /* eglswapbuffers must be called only after all active devices have finished rendering inorder to avoid any artifacts due to incomplete/partial frame updates*/ eglSwapBuffers(dpy, surface); } else { sleep(2); } } return 0; }
/* Resets a channel to start of script next time it runs. */ bool sdma_channel_reset(unsigned int channel) { struct channel_control_block *ccb_p; if (channel == 0 || channel >= CH_NUM) return false; ccb_p = &ccb_array[channel]; if (ccb_p->status.opened_init == 0) return false; if (!setup_channel(ccb_p)) return false; return true; }
static int open_channel(orte_rmcast_channel_t channel, char *name, char *network, int port, char *interface, uint8_t direction) { opal_list_item_t *item; rmcast_base_channel_t *nchan, *chan; uint32_t netaddr=0, netmask=0, intr=0; int rc; unsigned int i, n, start, end, range; bool port_assigned; OPAL_OUTPUT_VERBOSE((2, orte_rmcast_base.rmcast_output, "%s opening channel %d for %s", ORTE_NAME_PRINT(ORTE_PROC_MY_NAME), channel, name)); /* parse the network, if provided */ if (NULL != network) { if (ORTE_SUCCESS != (rc = opal_iftupletoaddr(network, &netaddr, &netmask))) { orte_show_help("help-rmcast-base.txt", "invalid-net-mask", true, network, ORTE_ERROR_NAME(rc)); return ORTE_ERR_SILENT; } } /* parse the interface, if provided */ if (NULL != interface) { if (ORTE_SUCCESS != (rc = opal_iftupletoaddr(interface, &intr, NULL))) { orte_show_help("help-rmcast-base.txt", "invalid-net-mask", true, interface, ORTE_ERROR_NAME(rc)); return ORTE_ERR_SILENT; } } /* see if this name has already been assigned a channel on the specified network */ OPAL_OUTPUT_VERBOSE((7, orte_rmcast_base.rmcast_output, "%s open_channel: searching for %s:%d", ORTE_NAME_PRINT(ORTE_PROC_MY_NAME), name, channel)); chan = NULL; ORTE_ACQUIRE_THREAD(&orte_rmcast_base.main_ctl); for (item = opal_list_get_first(&orte_rmcast_base.channels); item != opal_list_get_end(&orte_rmcast_base.channels); item = opal_list_get_next(item)) { nchan = (rmcast_base_channel_t*)item; OPAL_OUTPUT_VERBOSE((7, orte_rmcast_base.rmcast_output, "%s open_channel: channel %s:%d", ORTE_NAME_PRINT(ORTE_PROC_MY_NAME), nchan->name, channel)); if (nchan->channel == channel || 0 == strcasecmp(nchan->name, name)) { chan = nchan; break; } } if (NULL != chan) { /* already exists - check that the requested * sockets are setup */ OPAL_OUTPUT_VERBOSE((2, orte_rmcast_base.rmcast_output, "%s rmcast:udp using existing channel %s:%d network %03d.%03d.%03d.%03d port %d", ORTE_NAME_PRINT(ORTE_PROC_MY_NAME), chan->name, chan->channel, OPAL_IF_FORMAT_ADDR(chan->network), (int)chan->port)); if (ORTE_SUCCESS != (rc = setup_channel(chan, direction))) { ORTE_ERROR_LOG(rc); ORTE_RELEASE_THREAD(&orte_rmcast_base.main_ctl); return rc; } ORTE_RELEASE_THREAD(&orte_rmcast_base.main_ctl); return ORTE_SUCCESS; } /* we didn't find an existing match, so create a new channel */ OPAL_OUTPUT_VERBOSE((2, orte_rmcast_base.rmcast_output, "%s creating new channel %s for %s", ORTE_NAME_PRINT(ORTE_PROC_MY_NAME), orte_rmcast_base_print_channel(channel), name)); chan = OBJ_NEW(rmcast_base_channel_t); chan->name = strdup(name); chan->channel = channel; /* if we were not given a network, use the default */ if (NULL == network) { chan->network = orte_rmcast_base.xmit_network; } else { chan->network = netaddr; } /* if we were not given an interface, use the default */ if (NULL == interface) { chan->interface = orte_rmcast_base.interface; } else { chan->interface = intr; } /* if we were not given a port, use a default one */ if (port < 0) { /* cycle thru the port ranges until we find the * port corresponding to this channel number */ n=0; port_assigned = false; for (i=0; NULL != orte_rmcast_base.ports.start[i]; i++) { /* how many ports are in this range? */ start = strtol(orte_rmcast_base.ports.start[i], NULL, 10); end = strtol(orte_rmcast_base.ports.end[i], NULL, 10); range = end - start + 1; if (chan->channel < (n + range)) { /* take the corresponding port */ chan->port = start + (chan->channel - n); port_assigned = true; break; } n += range; } if (!port_assigned) { opal_output(0, "%s CANNOT ASSIGN PORT TO CHANNEL %s", ORTE_NAME_PRINT(ORTE_PROC_MY_NAME), orte_rmcast_base_print_channel(chan->channel)); return ORTE_ERROR; } } else { chan->port = port; } opal_list_append(&orte_rmcast_base.channels, &chan->item); ORTE_RELEASE_THREAD(&orte_rmcast_base.main_ctl); /* if this is my input, set that value */ if (ORTE_RMCAST_MY_INPUT & direction) { orte_rmcast_base.my_input_channel = chan; } /* if this is my output, set that value */ if (ORTE_RMCAST_MY_OUTPUT & direction) { orte_rmcast_base.my_output_channel = chan; } OPAL_OUTPUT_VERBOSE((2, orte_rmcast_base.rmcast_output, "%s rmcast:udp opening new channel %s:%s network %03d.%03d.%03d.%03d port %d for%s%s", ORTE_NAME_PRINT(ORTE_PROC_MY_NAME), chan->name, orte_rmcast_base_print_channel(chan->channel), OPAL_IF_FORMAT_ADDR(chan->network), (int)chan->port, (ORTE_RMCAST_RECV & direction) ? " RECV" : " ", (ORTE_RMCAST_XMIT & direction) ? " XMIT" : " ")); if (ORTE_SUCCESS != (rc = setup_channel(chan, direction))) { ORTE_ERROR_LOG(rc); return rc; } return ORTE_SUCCESS; }
vrpn_Tracker_ButtonFly::vrpn_Tracker_ButtonFly (const char * name, vrpn_Connection * trackercon, vrpn_Tracker_ButtonFlyParam * params, float update_rate, bool reportChanges) : vrpn_Tracker (name, trackercon), d_vel_scale(NULL), d_vel_scale_value(1.0), d_rot_scale(NULL), d_rot_scale_value(1.0), d_update_interval (update_rate ? (1/update_rate) : 1.0), d_reportChanges (reportChanges) { int i; //-------------------------------------------------------------------- // Copy the parameter values and initialize the values and pointers // in the list of axes. The setup_channel() call opens the button // remote and sets up a callback to handle the changes. d_num_axes = params->num_axes; for (i = 0; i < params->num_axes; i++) { d_axes[i].axis = params->axes[i]; d_axes[i].active = false; d_axes[i].bf = this; setup_channel(&d_axes[i]); } //-------------------------------------------------------------------- // Open the scale analogs if they have non-NULL names. // If the name starts with the "*" character, use tracker // connection rather than getting a new connection for it. // Set up a callback for each to set the scale factor. if (params->vel_scale_name != NULL) { // Copy the parameters into our member variables d_vel_scale_channel = params->vel_scale_channel; d_vel_scale_offset = params->vel_scale_offset; d_vel_scale_scale = params->vel_scale_scale; d_vel_scale_power = params->vel_scale_power; // Open the analog device and point the remote at it. // If the name starts with the '*' character, use // the server connection rather than making a new one. if (params->vel_scale_name[0] == '*') { d_vel_scale = new vrpn_Analog_Remote (&(params->vel_scale_name[1]), d_connection); } else { d_vel_scale = new vrpn_Analog_Remote(params->vel_scale_name); } // Set up the callback handler if (d_vel_scale == NULL) { fprintf(stderr,"vrpn_Tracker_ButtonFly: " "Can't open Analog %s\n",params->vel_scale_name); } else { // Set up the callback handler for the channel d_vel_scale->register_change_handler(this, handle_velocity_update); } } if (params->rot_scale_name != NULL) { // Copy the parameters into our member variables d_rot_scale_channel = params->rot_scale_channel; d_rot_scale_offset = params->rot_scale_offset; d_rot_scale_scale = params->rot_scale_scale; d_rot_scale_power = params->rot_scale_power; // Open the analog device and point the remote at it. // If the name starts with the '*' character, use // the server connection rather than making a new one. if (params->rot_scale_name[0] == '*') { d_rot_scale = new vrpn_Analog_Remote (&(params->rot_scale_name[1]), d_connection); } else { d_rot_scale = new vrpn_Analog_Remote(params->rot_scale_name); } // Set up the callback handler if (d_rot_scale == NULL) { fprintf(stderr,"vrpn_Tracker_ButtonFly: " "Can't open Analog %s\n",params->rot_scale_name); } else { // Set up the callback handler for the channel d_rot_scale->register_change_handler(this, handle_rotation_update); } } //-------------------------------------------------------------------- // Whenever we get the first connection to this server, we also // want to reset the matrix to identity, so that you start at the // beginning. Set up a handler to do this. register_autodeleted_handler(d_connection->register_message_type (vrpn_got_first_connection), handle_newConnection, this); //-------------------------------------------------------------------- // Set the initialization matrix to identity, then also set // the current matrix to identity. for ( i =0; i< 4; i++) for (int j=0; j< 4; j++) d_initMatrix[i][j] = 0; d_initMatrix[0][0] = d_initMatrix[1][1] = d_initMatrix[2][2] = d_initMatrix[3][3] = 1.0; reset(); }
vrpn_Tracker_AnalogFly::vrpn_Tracker_AnalogFly (const char * name, vrpn_Connection * trackercon, vrpn_Tracker_AnalogFlyParam * params, float update_rate, bool absolute, bool reportChanges, bool worldFrame) : vrpn_Tracker (name, trackercon), d_update_interval (update_rate ? (1/update_rate) : 1.0), d_absolute (absolute), d_reportChanges (reportChanges), d_worldFrame (worldFrame), d_reset_button(NULL), d_which_button (params->reset_which), d_clutch_button(NULL), d_clutch_which (params->clutch_which), d_clutch_engaged(false), d_clutch_was_off(false) { int i; d_x.axis = params->x; d_y.axis = params->y; d_z.axis = params->z; d_sx.axis = params->sx; d_sy.axis = params->sy; d_sz.axis = params->sz; d_x.ana = d_y.ana = d_z.ana = NULL; d_sx.ana = d_sy.ana = d_sz.ana = NULL; d_x.value = d_y.value = d_z.value = 0.0; d_sx.value = d_sy.value = d_sz.value = 0.0; d_x.af = this; d_y.af = this; d_z.af = this; d_sx.af = this; d_sy.af = this; d_sz.af = this; //-------------------------------------------------------------------- // Open analog remotes for any channels that have non-NULL names. // If the name starts with the "*" character, use tracker // connection rather than getting a new connection for it. // Set up callbacks to handle updates to the analog values setup_channel(&d_x); setup_channel(&d_y); setup_channel(&d_z); setup_channel(&d_sx); setup_channel(&d_sy); setup_channel(&d_sz); //-------------------------------------------------------------------- // Open the reset button if is has a non-NULL name. // If the name starts with the "*" character, use tracker // connection rather than getting a new connection for it. // Set up callback for it to reset the matrix to identity. // If the name is NULL, don't do anything. if (params->reset_name != NULL) { // Open the button device and point the remote at it. // If the name starts with the '*' character, use // the server connection rather than making a new one. if (params->reset_name[0] == '*') { try { d_reset_button = new vrpn_Button_Remote (&(params->reset_name[1]), d_connection); } catch (...) { d_reset_button = NULL; } } else { try { d_reset_button = new vrpn_Button_Remote (params->reset_name); } catch (...) { d_reset_button = NULL; } } if (d_reset_button == NULL) { fprintf(stderr,"vrpn_Tracker_AnalogFly: " "Can't open Button %s\n",params->reset_name); } else { // Set up the callback handler for the channel d_reset_button->register_change_handler (this, handle_reset_press); } } //-------------------------------------------------------------------- // Open the clutch button if is has a non-NULL name. // If the name starts with the "*" character, use tracker // connection rather than getting a new connection for it. // Set up callback for it to control clutching. // If the name is NULL, don't do anything. if (params->clutch_name != NULL) { // Open the button device and point the remote at it. // If the name starts with the '*' character, use // the server connection rather than making a new one. if (params->clutch_name[0] == '*') { try { d_clutch_button = new vrpn_Button_Remote (&(params->clutch_name[1]), d_connection); } catch (...) { d_clutch_button = NULL; } } else { try { d_clutch_button = new vrpn_Button_Remote (params->clutch_name); } catch (...) { d_clutch_button = NULL; } } if (d_clutch_button == NULL) { fprintf(stderr,"vrpn_Tracker_AnalogFly: " "Can't open Button %s\n",params->clutch_name); } else { // Set up the callback handler for the channel d_clutch_button->register_change_handler (this, handle_clutch_press); } } // If the clutch button is NULL, then engage the clutch always. if (params->clutch_name == NULL) { d_clutch_engaged = true; } //-------------------------------------------------------------------- // Whenever we get the first connection to this server, we also // want to reset the matrix to identity, so that you start at the // beginning. Set up a handler to do this. register_autodeleted_handler(d_connection->register_message_type(vrpn_got_first_connection), handle_newConnection, this); //-------------------------------------------------------------------- // Set the initialization matrix to identity, then also set // the current matrix to identity and the clutch matrix to // identity. for ( i =0; i< 4; i++) { for (int j=0; j< 4; j++) { d_initMatrix[i][j] = 0; } } d_initMatrix[0][0] = d_initMatrix[1][1] = d_initMatrix[2][2] = d_initMatrix[3][3] = 1.0; reset(); q_matrix_copy(d_clutchMatrix, d_initMatrix); q_matrix_copy(d_currentMatrix, d_initMatrix); //-------------------------------------------------------------------- // Set the current timestamp to "now" and current matrix to identity // for absolute trackers. This is done in case we never hear from the // analog devices. Reset doesn't do this for absolute trackers. if (d_absolute) { vrpn_gettimeofday(&d_prevtime, NULL); vrpn_Tracker::timestamp = d_prevtime; q_matrix_copy(d_currentMatrix, d_initMatrix); convert_matrix_to_tracker(); } }
// buffer recv/send size limit CASE_TEST(channel, io_stream_tcp_size_extended) { atbus::channel::io_stream_channel svr, cli; atbus::channel::io_stream_conf conf; atbus::channel::io_stream_init_configure(&conf); conf.send_buffer_limit_size = conf.recv_buffer_max_size + 1; atbus::channel::io_stream_init(&svr, NULL, &conf); atbus::channel::io_stream_init(&cli, NULL, &conf); svr.evt.callbacks[atbus::channel::io_stream_callback_evt_t::EN_FN_RECVED] = recv_size_err_callback_check_fn; cli.evt.callbacks[atbus::channel::io_stream_callback_evt_t::EN_FN_RECVED] = recv_size_err_callback_check_fn; svr.evt.callbacks[atbus::channel::io_stream_callback_evt_t::EN_FN_DISCONNECTED] = disconnected_callback_test_fn; svr.evt.callbacks[atbus::channel::io_stream_callback_evt_t::EN_FN_DISCONNECTED] = disconnected_callback_test_fn; int check_flag = g_check_flag = 0; int inited_fds = 0; inited_fds += setup_channel(svr, "ipv6://:::16387", NULL); CASE_EXPECT_EQ(1, g_check_flag); CASE_EXPECT_NE(NULL, svr.ev_loop); inited_fds = 0; inited_fds += setup_channel(cli, NULL, "ipv4://127.0.0.1:16387"); while (g_check_flag - check_flag < 2 * inited_fds) { atbus::channel::io_stream_run(&svr, atbus::adapter::RUN_NOWAIT); atbus::channel::io_stream_run(&cli, atbus::adapter::RUN_NOWAIT); CASE_THREAD_SLEEP_MS(8); } CASE_EXPECT_NE(0, cli.conn_pool.size()); check_flag = g_check_flag; int res = atbus::channel::io_stream_send(cli.conn_pool.begin()->second.get(), get_test_buffer(), conf.recv_buffer_limit_size + 1); CASE_EXPECT_EQ(0, res); res = atbus::channel::io_stream_send(cli.conn_pool.begin()->second.get(), get_test_buffer(), conf.send_buffer_limit_size + 1); CASE_EXPECT_EQ(EN_ATBUS_ERR_INVALID_SIZE, res); while (g_check_flag - check_flag < 1) { atbus::channel::io_stream_run(&svr, atbus::adapter::RUN_NOWAIT); atbus::channel::io_stream_run(&cli, atbus::adapter::RUN_NOWAIT); CASE_THREAD_SLEEP_MS(32); } // 错误的数据大小会导致连接断开 res = atbus::channel::io_stream_send(cli.conn_pool.begin()->second.get(), get_test_buffer(), conf.send_buffer_limit_size); CASE_EXPECT_EQ(0, res); // 有接收端关闭,所以一定是接收端先出发关闭连接。 // 这里只要判定后触发方完成回调,那么先触发方必然已经完成 while (!cli.conn_pool.empty()) { atbus::channel::io_stream_run(&svr, atbus::adapter::RUN_NOWAIT); atbus::channel::io_stream_run(&cli, atbus::adapter::RUN_NOWAIT); CASE_THREAD_SLEEP_MS(32); } CASE_EXPECT_EQ(0, cli.conn_pool.size()); CASE_EXPECT_EQ(1, svr.conn_pool.size()); atbus::channel::io_stream_close(&cli); atbus::channel::io_stream_close(&svr); }
CASE_TEST(channel, io_stream_tcp_basic) { atbus::adapter::loop_t loop; uv_loop_init(&loop); atbus::channel::io_stream_channel svr, cli; atbus::channel::io_stream_init(&svr, &loop, NULL); atbus::channel::io_stream_init(&cli, &loop, NULL); CASE_EXPECT_EQ(&loop, svr.ev_loop); CASE_EXPECT_EQ(&loop, cli.ev_loop); g_check_flag = 0; int inited_fds = 0; inited_fds += setup_channel(svr, "ipv6://:::16387", NULL); CASE_EXPECT_EQ(1, g_check_flag); CASE_EXPECT_NE(NULL, svr.ev_loop); if (0 == inited_fds) { uv_loop_close(&loop); return; } inited_fds = 0; inited_fds += setup_channel(cli, NULL, "ipv4://127.0.0.1:16387"); inited_fds += setup_channel(cli, NULL, "dns://localhost:16387"); inited_fds += setup_channel(cli, NULL, "ipv6://::1:16387"); int check_flag = g_check_flag; while (g_check_flag - check_flag < 2 * inited_fds) { uv_run(&loop, UV_RUN_ONCE); } svr.evt.callbacks[atbus::channel::io_stream_callback_evt_t::EN_FN_RECVED] = recv_callback_check_fn; cli.evt.callbacks[atbus::channel::io_stream_callback_evt_t::EN_FN_RECVED] = recv_callback_check_fn; char* buf = get_test_buffer(); check_flag = g_check_flag; // small buffer atbus::channel::io_stream_send(cli.conn_pool.begin()->second.get(), buf, 13); g_check_buff_sequence.push_back(std::make_pair(0, 13)); atbus::channel::io_stream_send(cli.conn_pool.begin()->second.get(), buf + 13, 28); g_check_buff_sequence.push_back(std::make_pair(13, 28)); atbus::channel::io_stream_send(cli.conn_pool.begin()->second.get(), buf + 13 + 28, 100); g_check_buff_sequence.push_back(std::make_pair(13 + 28, 100)); // big buffer atbus::channel::io_stream_send(cli.conn_pool.begin()->second.get(), buf + 1024, 56 * 1024 + 3); g_check_buff_sequence.push_back(std::make_pair(1024, 56 * 1024 + 3)); while (g_check_flag - check_flag < 4) { uv_run(&loop, UV_RUN_ONCE); } // many big buffer { check_flag = g_check_flag; atbus::channel::io_stream_channel::conn_pool_t::iterator it = svr.conn_pool.begin(); // 跳过listen的socket if (it->second->addr.address == "ipv6://:::16387") { ++it; } size_t sum_size = 0; g_recv_rec = std::make_pair(0, 0); for (int i = 0; i < 153; ++ i) { size_t s = static_cast<size_t>(rand() % 2048); size_t l = static_cast<size_t>(rand() % 10240) + 20 * 1024; atbus::channel::io_stream_send(it->second.get(), buf + s, l); g_check_buff_sequence.push_back(std::make_pair(s, l)); sum_size += l; } CASE_MSG_INFO() << "send " << sum_size << " bytes data with " << g_check_buff_sequence.size() << " packages done." << std::endl; while (g_check_flag - check_flag < 153) { uv_run(&loop, UV_RUN_ONCE); } CASE_MSG_INFO() << "recv " << g_recv_rec.second << " bytes data with " << g_recv_rec.first << " packages and checked done." << std::endl; } atbus::channel::io_stream_close(&svr); atbus::channel::io_stream_close(&cli); CASE_EXPECT_EQ(0, svr.conn_pool.size()); CASE_EXPECT_EQ(0, cli.conn_pool.size()); uv_loop_close(&loop); }
vrpn_Poser_Analog::vrpn_Poser_Analog(const char* name, vrpn_Connection * c, vrpn_Poser_AnalogParam* p, bool act_as_tracker) : vrpn_Poser(name, c), vrpn_Tracker(name, c), d_act_as_tracker(act_as_tracker) { int i; // register_server_handlers(); // Make sure that we have a valid connection if (d_connection == NULL) { fprintf(stderr,"vrpn_Poser_Analog: No connection\n"); return; } // Register a handler for the position change callback for this device if (register_autodeleted_handler(req_position_m_id, handle_change_message, this, d_sender_id)) { fprintf(stderr,"vrpn_Poser_Analog: can't register position handler\n"); d_connection = NULL; } // Register a handler for the velocity change callback for this device if (register_autodeleted_handler(req_velocity_m_id, handle_vel_change_message, this, d_sender_id)) { fprintf(stderr,"vrpn_Poser_Analog: can't register velocity handler\n"); d_connection = NULL; } // Set up the axes x.axis = p->x; y.axis = p->y; z.axis = p->z; rx.axis = p->rx; ry.axis = p->ry; rz.axis = p->rz; x.ana = y.ana = z.ana = NULL; rx.ana = ry.ana = rz.ana = NULL; x.value = y.value = z.value = 0.0; rx.value = ry.value = rz.value = 0.0; x.pa = this; y.pa = this; z.pa = this; rx.pa = this; ry.pa = this; rz.pa = this; //-------------------------------------------------------------------- // Open analog remotes for any channels that have non-NULL names. // If the name starts with the "*" character, use tracker // connection rather than getting a new connection for it. setup_channel(&x); setup_channel(&y); setup_channel(&z); setup_channel(&rx); setup_channel(&ry); setup_channel(&rz); // Set up the workspace max and min values for (i = 0; i < 3; i++) { p_pos_min[i] = p->pos_min[i]; p_pos_max[i] = p->pos_max[i]; p_vel_min[i] = p->vel_min[i]; p_vel_max[i] = p->vel_max[i]; p_pos_rot_min[i] = p->pos_rot_min[i]; p_pos_rot_max[i] = p->pos_rot_max[i]; p_vel_rot_min[i] = p->vel_rot_min[i]; p_vel_rot_max[i] = p->vel_rot_max[i]; } // Check the pose for each channel against the max and min values of the workspace // and set it to the location closest to the origin. p_pos[0] = p_pos[1] = p_pos[2] = 0.0; p_quat[0] = p_quat[1] = p_quat[2] = 0.0; p_quat[3] = 1.0; for (i = 0; i < 3; i++) { if (p_pos[i] < p_pos_min[i]) { p_pos[i] = p_pos_min[i]; } else if (p_pos[i] > p_pos_max[i]) { p_pos[i] = p_pos_max[i]; } } }
int main(int argc, char *argv[]) { int daemonize = 0; char *pidfile = NULL; char *envarea = NULL; int cnid = -1; pcre *msgfilter = NULL; pcre *stdfilter = NULL; int argi; struct sigaction sa; RbtIterator handle; /* Dont save the error buffer */ save_errbuf = 0; /* Create the peer container */ peers = rbtNew(name_compare); for (argi=1; (argi < argc); argi++) { if (argnmatch(argv[argi], "--debug")) { debug = 1; } else if (argnmatch(argv[argi], "--channel=")) { char *cn = strchr(argv[argi], '=') + 1; for (cnid = C_STATUS; (channelnames[cnid] && strcmp(channelnames[cnid], cn)); cnid++) ; if (channelnames[cnid] == NULL) cnid = -1; } else if (argnmatch(argv[argi], "--daemon")) { daemonize = 1; } else if (argnmatch(argv[argi], "--no-daemon")) { daemonize = 0; } else if (argnmatch(argv[argi], "--pidfile=")) { char *p = strchr(argv[argi], '='); pidfile = strdup(p+1); } else if (argnmatch(argv[argi], "--log=")) { char *p = strchr(argv[argi], '='); logfn = strdup(p+1); } else if (argnmatch(argv[argi], "--env=")) { char *p = strchr(argv[argi], '='); loadenv(p+1, envarea); } else if (argnmatch(argv[argi], "--area=")) { char *p = strchr(argv[argi], '='); envarea = strdup(p+1); } else if (argnmatch(argv[argi], "--locator=")) { char *p = strchr(argv[argi], '='); locator_init(p+1); locatorbased = 1; } else if (argnmatch(argv[argi], "--service=")) { char *p = strchr(argv[argi], '='); locatorservice = get_servicetype(p+1); } else if (argnmatch(argv[argi], "--filter=")) { char *p = strchr(argv[argi], '='); msgfilter = compileregex(p+1); if (!msgfilter) { errprintf("Invalid filter (bad expression): %s\n", p+1); } else { stdfilter = compileregex("^@@(logrotate|shutdown|drophost|droptest|renamehost|renametest)"); } } else { char *childcmd; char **childargs; int i = 0; childcmd = argv[argi]; childargs = (char **) calloc((1 + argc - argi), sizeof(char *)); while (argi < argc) { childargs[i++] = argv[argi++]; } addlocalpeer(childcmd, childargs); } } /* Sanity checks */ if (cnid == -1) { errprintf("No channel/unknown channel specified\n"); return 1; } if (locatorbased && (locatorservice == ST_MAX)) { errprintf("Must specify --service when using locator\n"); return 1; } if (!locatorbased && (rbtBegin(peers) == rbtEnd(peers))) { errprintf("Must specify command for local worker\n"); return 1; } /* Do cache responses to avoid doing too many lookups */ if (locatorbased) locator_prepcache(locatorservice, 0); /* Go daemon */ if (daemonize) { /* Become a daemon */ pid_t daemonpid = fork(); if (daemonpid < 0) { /* Fork failed */ errprintf("Could not fork child\n"); exit(1); } else if (daemonpid > 0) { /* Parent creates PID file and exits */ FILE *fd = NULL; if (pidfile) fd = fopen(pidfile, "w"); if (fd) { fprintf(fd, "%d\n", (int)daemonpid); fclose(fd); } exit(0); } /* Child (daemon) continues here */ setsid(); } /* Catch signals */ setup_signalhandler("xymond_channel"); memset(&sa, 0, sizeof(sa)); sa.sa_handler = sig_handler; sigaction(SIGINT, &sa, NULL); sigaction(SIGTERM, &sa, NULL); sigaction(SIGCHLD, &sa, NULL); signal(SIGALRM, SIG_IGN); /* Switch stdout/stderr to the logfile, if one was specified */ freopen("/dev/null", "r", stdin); /* xymond_channel's stdin is not used */ if (logfn) { freopen(logfn, "a", stdout); freopen(logfn, "a", stderr); } /* Attach to the channel */ channel = setup_channel(cnid, CHAN_CLIENT); if (channel == NULL) { errprintf("Channel not available\n"); running = 0; } while (running) { /* * Wait for GOCLIENT to go up. * * Note that we use IPC_NOWAIT if there are messages in the * queue, because then we just want to pick up a message if * there is one, and if not we want to continue pushing the * queued data to the worker. */ struct sembuf s; int n; s.sem_num = GOCLIENT; s.sem_op = -1; s.sem_flg = ((pendingcount > 0) ? IPC_NOWAIT : 0); n = semop(channel->semid, &s, 1); if (n == 0) { /* * GOCLIENT went high, and so we got alerted about a new * message arriving. Copy the message to our own buffer queue. */ char *inbuf = NULL; if (!msgfilter || matchregex(channel->channelbuf, msgfilter) || matchregex(channel->channelbuf, stdfilter)) { inbuf = strdup(channel->channelbuf); } /* * Now we have safely stored the new message in our buffer. * Wait until any other clients on the same channel have picked up * this message (GOCLIENT reaches 0). * * We wrap this into an alarm handler, because it can occasionally * fail, causing the whole system to lock up. We dont want that.... * We'll set the alarm to trigger after 1 second. Experience shows * that we'll either succeed in a few milliseconds, or fail completely * and wait the full alarm-timer duration. */ gotalarm = 0; signal(SIGALRM, sig_handler); alarm(2); do { s.sem_num = GOCLIENT; s.sem_op = 0; s.sem_flg = 0; n = semop(channel->semid, &s, 1); } while ((n == -1) && (errno == EAGAIN) && running && (!gotalarm)); signal(SIGALRM, SIG_IGN); if (gotalarm) { errprintf("Gave up waiting for GOCLIENT to go low.\n"); } /* * Let master know we got it by downing BOARDBUSY. * This should not block, since BOARDBUSY is upped * by the master just before he ups GOCLIENT. */ do { s.sem_num = BOARDBUSY; s.sem_op = -1; s.sem_flg = IPC_NOWAIT; n = semop(channel->semid, &s, 1); } while ((n == -1) && (errno == EINTR)); if (n == -1) { errprintf("Tried to down BOARDBUSY: %s\n", strerror(errno)); } if (inbuf) { /* * See if they want us to rotate logs. We pass this on to * the worker module as well, but must handle our own logfile. */ if (strncmp(inbuf, "@@logrotate", 11) == 0) { freopen(logfn, "a", stdout); freopen(logfn, "a", stderr); } /* * Put the new message on our outbound queue. */ if (addmessage(inbuf) != 0) { /* Failed to queue message, free the buffer */ xfree(inbuf); } } } else { if (errno != EAGAIN) { dbgprintf("Semaphore wait aborted: %s\n", strerror(errno)); continue; } } /* * We've picked up messages from the master. Now we * must push them to the worker process. Since there * is no way to hang off both a semaphore and select(), * we'll just push as much data as possible into the * pipe. If we get to a point where we would block, * then wait a teeny bit of time and restart the * whole loop with checking for new messages from the * master etc. * * In theory, this could become an almost busy-wait loop. * In practice, however, the queue will be empty most * of the time because we'll just shove the data to the * worker child. */ for (handle = rbtBegin(peers); (handle != rbtEnd(peers)); handle = rbtNext(peers, handle)) { int canwrite = 1, hasfailed = 0; xymon_peer_t *pwalk; time_t msgtimeout = gettimer() - MSGTIMEOUT; int flushcount = 0; pwalk = (xymon_peer_t *) gettreeitem(peers, handle); if (pwalk->msghead == NULL) continue; /* Ignore peers with nothing queued */ switch (pwalk->peerstatus) { case P_UP: canwrite = 1; break; case P_DOWN: openconnection(pwalk); canwrite = (pwalk->peerstatus == P_UP); break; case P_FAILED: canwrite = 0; break; } /* See if we have stale messages queued */ while (pwalk->msghead && (pwalk->msghead->tstamp < msgtimeout)) { flushmessage(pwalk); flushcount++; } if (flushcount) { errprintf("Flushed %d stale messages for %s:%d\n", flushcount, inet_ntoa(pwalk->peeraddr.sin_addr), ntohs(pwalk->peeraddr.sin_port)); } while (pwalk->msghead && canwrite) { fd_set fdwrite; struct timeval tmo; /* Check that this peer is ready for writing. */ FD_ZERO(&fdwrite); FD_SET(pwalk->peersocket, &fdwrite); tmo.tv_sec = 0; tmo.tv_usec = 2000; n = select(pwalk->peersocket+1, NULL, &fdwrite, NULL, &tmo); if (n == -1) { errprintf("select() failed: %s\n", strerror(errno)); canwrite = 0; hasfailed = 1; continue; } else if ((n == 0) || (!FD_ISSET(pwalk->peersocket, &fdwrite))) { canwrite = 0; continue; } n = write(pwalk->peersocket, pwalk->msghead->bufp, pwalk->msghead->buflen); if (n >= 0) { pwalk->msghead->bufp += n; pwalk->msghead->buflen -= n; if (pwalk->msghead->buflen == 0) flushmessage(pwalk); } else if (errno == EAGAIN) { /* * Write would block ... stop for now. */ canwrite = 0; } else { hasfailed = 1; } if (hasfailed) { /* Write failed, or message grew stale */ errprintf("Peer at %s:%d failed: %s\n", inet_ntoa(pwalk->peeraddr.sin_addr), ntohs(pwalk->peeraddr.sin_port), strerror(errno)); canwrite = 0; shutdownconnection(pwalk); if (pwalk->peertype == P_NET) locator_serverdown(pwalk->peername, locatorservice); pwalk->peerstatus = P_FAILED; } } } } /* Detach from channels */ close_channel(channel, CHAN_CLIENT); /* Close peer connections */ for (handle = rbtBegin(peers); (handle != rbtEnd(peers)); handle = rbtNext(peers, handle)) { xymon_peer_t *pwalk = (xymon_peer_t *) gettreeitem(peers, handle); shutdownconnection(pwalk); } /* Remove the PID file */ if (pidfile) unlink(pidfile); return 0; }