void o2fsck_compute_resource_track(struct o2fsck_resource_track *rt, io_channel *channel) { struct rusage r; struct timeval time_end; struct ocfs2_io_stats _ios, *ios = &_ios; struct ocfs2_io_stats *rtio = &rt->rt_io_stats; getrusage(RUSAGE_SELF, &r); gettimeofday(&time_end, 0); diff_timeval(&r.ru_utime, &rt->rt_user_time); diff_timeval(&r.ru_stime, &rt->rt_sys_time); diff_timeval(&time_end, &rt->rt_real_time); memcpy(&rt->rt_user_time, &r.ru_utime, sizeof(struct timeval)); memcpy(&rt->rt_sys_time, &r.ru_stime, sizeof(struct timeval)); memcpy(&rt->rt_real_time, &time_end, sizeof(struct timeval)); io_get_stats(channel, ios); rtio->is_bytes_read = ios->is_bytes_read - rtio->is_bytes_read; rtio->is_bytes_written = ios->is_bytes_written - rtio->is_bytes_written; rtio->is_cache_hits = ios->is_cache_hits - rtio->is_cache_hits; rtio->is_cache_misses = ios->is_cache_misses - rtio->is_cache_misses; rtio->is_cache_inserts = ios->is_cache_inserts - rtio->is_cache_inserts; rtio->is_cache_removes = ios->is_cache_removes - rtio->is_cache_removes; }
void interrupt_main() { //printf("<-----CTR+C RECIEVED------>\n"); SERVER_DIE = 1; pthread_kill(TOKEN, SIGUSR1); pthread_kill(PACKET, SIGUSR2); pthread_mutex_lock(&m); //printf("Inside mutex of Man\n"); while(!My402ListEmpty(Q2)){ My402ListElem *elem = My402ListFirst(Q2); My402dataElem *topEle = (My402dataElem*)(elem->obj); My402ListUnlink(Q2, elem); TIME_AT_Q1 = diff_timeval(TIME_AT_Q1, topEle->q1duration); } /* Clear the list */ My402ListUnlinkAll(Q1); pthread_mutex_unlock(&m); pthread_cond_broadcast(&cond_t); //printf("<-----MAIN DYING------>\n"); pthread_exit(0); }
/** * Sets the fields in a EXT_TFMCC_ACK_INFO extension for transmission */ void set_tfmcc_ack_info(struct group_list_t *group, struct tfmcc_ack_info_he *tfmcc) { struct timeval now, send_time; unsigned ccrate; tfmcc->exttype = EXT_TFMCC_ACK_INFO; tfmcc->extlen = sizeof(struct tfmcc_ack_info_he) / 4; tfmcc->cc_seq = htons(group->ccseq); ccrate = current_cc_rate(group); glog4(group, "ccrate=%d", ccrate); tfmcc->cc_rate = htons(quantize_rate(ccrate)); //tfmcc->cc_rate = htons(quantize_rate(current_cc_rate(group))); tfmcc->flags = 0; if (group->slowstart) { tfmcc->flags |= FLAG_CC_START; } if (group->rtt != 0.0) { tfmcc->flags |= FLAG_CC_RTT; } tfmcc->client_id = uid; gettimeofday(&now, NULL); if (cmptimestamp(now, group->last_server_rx_ts) <= 0) { send_time = group->last_server_ts; } else { send_time = add_timeval(group->last_server_ts, diff_timeval(now, group->last_server_rx_ts)); } tfmcc->tstamp_sec = htonl((uint32_t)send_time.tv_sec); tfmcc->tstamp_usec = htonl((uint32_t)send_time.tv_usec); }
int main( void ) { int rc = 0; struct timezone tz = { 240, 1 }; struct timeval begin_timeval; struct timeval end_timeval; gettimeofday( &begin_timeval, &tz ); long i; jsonObject * pObj = NULL; for( i = 10000000; i; --i ) { // pObj = jsonParse( sample_json ); pObj = jsonNewObject( NULL ); jsonObject * p1 = jsonNewObject( NULL ); jsonObject * p2 = jsonNewObject( NULL ); jsonObjectFree( p1 ); jsonObjectFree( p2 ); jsonObjectFree( pObj ); } jsonObjectFreeUnused(); gettimeofday( &end_timeval, &tz ); struct timeval elapsed = diff_timeval( &begin_timeval, &end_timeval ); printf( "Elapsed time: %ld seconds, %ld microseconds\n", (long) elapsed.tv_sec, (long) elapsed.tv_usec ); struct rlimit rlim; if( getrlimit( RLIMIT_DATA, &rlim ) ) printf( "Error calling getrlimit\n" ); else printf( "Address space: %lu\n", (unsigned long) rlim.rlim_cur ); #ifdef HAVE_MALLOC_STATS malloc_stats(); #else fprintf(stderr, "malloc_stats() is not available on your system\n"); #endif return rc; }
void measure_gettimeofday(void) { struct timeval ta; struct timeval tb; int32_t granularity; int cnt = 0; gettimeofday(&ta, 0); tb = ta; while(tb.tv_usec == ta.tv_usec) { gettimeofday(&ta, 0); cnt++; } granularity = diff_timeval(&tb, &ta); printf("\tgettimeofday: %s%d ns\r\n", (cnt == 1 && granularity != 1000) ? "<=" : "", granularity); }
/* * Process timers on selector. The timeout is always set, to a very * long value if no timers are waiting. Note that this *must* be * called with sel->timer_lock held. Note that if this processes * any timers, the timeout will be set to { 0,0 }. */ static void process_timers(selector_t *sel, volatile struct timeval *timeout) { struct timeval now; sel_timer_t *timer; int called = 0; timer = theap_get_top(&sel->timer_heap); gettimeofday(&now, NULL); while (timer && cmp_timeval(&now, &timer->val.timeout) >= 0) { called = 1; theap_remove(&(sel->timer_heap), timer); timer->val.in_heap = 0; if (sel->have_timer_lock) sel->os_hnd->unlock(sel->os_hnd, sel->timer_lock); timer->val.handler(sel, timer, timer->val.user_data); if (sel->have_timer_lock) sel->os_hnd->lock(sel->os_hnd, sel->timer_lock); timer = theap_get_top(&sel->timer_heap); } if (called) { /* If called, set the timeout to zero. */ timeout->tv_sec = 0; timeout->tv_usec = 0; } else if (timer) { gettimeofday(&now, NULL); diff_timeval((struct timeval *) timeout, (struct timeval *) &timer->val.timeout, &now); } else { /* No timers, just set a long time. */ timeout->tv_sec = 100000; timeout->tv_usec = 0; } }
void sel_select_once(selector_t *sel) { fd_set tmp_read_set; fd_set tmp_write_set; fd_set tmp_except_set; int i; int err; sel_timer_t *timer; struct timeval timeout, *to_time; if (sel->timer_top) { struct timeval now; /* Check for timers to time out. */ gettimeofday(&now, NULL); timer = sel->timer_top; while (cmp_timeval(&now, &timer->timeout) >= 0) { remove_from_heap(&(sel->timer_top), &(sel->timer_last), timer); timer->in_heap = 0; timer->handler(sel, timer, timer->user_data); timer = sel->timer_top; gettimeofday(&now, NULL); if (!timer) goto no_timers; } /* Calculate how long to wait now. */ diff_timeval(&timeout, &sel->timer_top->timeout, &now); to_time = &timeout; } else { no_timers: to_time = NULL; } memcpy(&tmp_read_set, &sel->read_set, sizeof(tmp_read_set)); memcpy(&tmp_write_set, &sel->write_set, sizeof(tmp_write_set)); memcpy(&tmp_except_set, &sel->except_set, sizeof(tmp_except_set)); err = select(sel->maxfd+1, &tmp_read_set, &tmp_write_set, &tmp_except_set, to_time); if (err == 0) { /* A timeout occurred. */ } else if (err < 0) { /* An error occurred. */ if (errno == EINTR) { /* EINTR is ok, just restart the operation. */ timeout.tv_sec = 1; timeout.tv_usec = 0; } else { /* An error is bad, we need to abort. */ syslog(LOG_ERR, "select_loop() - select: %m"); exit(1); } } else { /* We got some I/O. */ for (i=0; i<=sel->maxfd; i++) { if (FD_ISSET(i, &tmp_read_set)) { if (sel->fds[i].handle_read == NULL) { /* Somehow we don't have a handler for this. Just shut it down. */ sel_set_fd_read_handler(sel, i, SEL_FD_HANDLER_DISABLED); } else { sel->fds[i].handle_read(i, sel->fds[i].data); } } if (FD_ISSET(i, &tmp_write_set)) { if (sel->fds[i].handle_write == NULL) { /* Somehow we don't have a handler for this. Just shut it down. */ sel_set_fd_write_handler(sel, i, SEL_FD_HANDLER_DISABLED); } else { sel->fds[i].handle_write(i, sel->fds[i].data); } } if (FD_ISSET(i, &tmp_except_set)) { if (sel->fds[i].handle_except == NULL) { /* Somehow we don't have a handler for this. Just shut it down. */ sel_set_fd_except_handler(sel, i, SEL_FD_HANDLER_DISABLED); } else { sel->fds[i].handle_except(i, sel->fds[i].data); } } } } if (got_sighup) { got_sighup = 0; if (user_sighup_handler != NULL) { user_sighup_handler(); } } if (got_sigint) { got_sigint = 0; if (user_sigint_handler != NULL) { user_sigint_handler(); } } }
/** * Gets the current timeout value to use for the main loop * * First check to see if any active groups have an expired timeout, and * handle that timeout. Once all expired timeouts have been handled, find * the active group with the earliest timeout and return the time until that * timeout. If there are no active groups, return NULL. */ struct timeval *getrecenttimeout(void) { static struct timeval tv = {0,0}; struct timeval current_timestamp, min_timestamp; int i, found_timeout, done, sent_naks; struct group_list_t *group; unsigned int section, nak_count; unsigned char *naks; gettimeofday(¤t_timestamp, NULL); done = 0; while (!done) { found_timeout = 0; done = 1; for (i = 0; i < MAXLIST; i++) { group = &group_list[i]; if (group->group_id != 0) { if (cmptimestamp(current_timestamp, group->timeout_time) >= 0) { switch (group->phase) { case PHASE_REGISTERED: send_register(group); break; case PHASE_RECEIVING: case PHASE_MIDGROUP: glog1(group, "Transfer timed out"); send_abort(group, "Transfer timed out"); break; case PHASE_COMPLETE: send_complete(group, 0); break; } done = 0; } else if ((!found_timeout) || (cmptimestamp(group->timeout_time, min_timestamp) < 0)) { glog5(group, "found min timeout time: %d:%06d", group->timeout_time.tv_sec, group->timeout_time.tv_usec); min_timestamp = group->timeout_time; found_timeout = 1; } // Check for a NAK timeout for sending a STATUS or COMPLETE if ((group->fileinfo.nak_time.tv_sec != 0) && cmptimestamp(current_timestamp, group->fileinfo.nak_time) >= 0) { group->fileinfo.nak_time.tv_sec = 0; group->fileinfo.nak_time.tv_usec = 0; // Send NAKs sent_naks = 0; retry_naks: for (section = group->fileinfo.nak_section_first; section < group->fileinfo.nak_section_last; section++) { naks = NULL; nak_count = get_naks(group, section, &naks); glog3(group, "read %d NAKs for section %d", nak_count, section); if (nak_count > 0) { send_status(group, section, naks, nak_count); sent_naks = 1; } free(naks); naks = NULL; } if (file_done(group, 1)) { glog2(group, "File transfer complete"); send_complete(group, 0); file_cleanup(group, 0); } else if (group->fileinfo.got_done && !sent_naks) { // We didn't send any NAKs since the last time // but the server is asking for some, // so check all prior sections group->fileinfo.nak_section_last = group->fileinfo.nak_section_first; group->fileinfo.nak_section_first = 0; group->fileinfo.got_done = 0; goto retry_naks; } } else if ((group->fileinfo.nak_time.tv_sec != 0) && ((!found_timeout) || (cmptimestamp(group->fileinfo.nak_time, min_timestamp) < 0))) { glog5(group, "found min nak time: %d:%06d", group->fileinfo.nak_time.tv_sec, group->fileinfo.nak_time.tv_usec); min_timestamp = group->fileinfo.nak_time; found_timeout = 1; } // Check congestion control feedback timer if (!group->isclr) { if ((group->cc_time.tv_sec != 0) && (cmptimestamp(current_timestamp, group->cc_time) >= 0)) { send_cc_ack(group); } else if ((group->cc_time.tv_sec != 0) && ((!found_timeout) || (cmptimestamp(group->cc_time, min_timestamp) < 0))) { glog5(group, "found min CC time: %d:%06d", group->cc_time.tv_sec, group->cc_time.tv_usec); min_timestamp = group->cc_time; found_timeout = 1; } } } } // Check timeout for proxy key request if (has_proxy && (proxy_pubkey.key == 0)) { if (cmptimestamp(current_timestamp, next_keyreq_time) >= 0) { send_key_req(); done = 0; } else if ((!found_timeout) || (cmptimestamp(next_keyreq_time, min_timestamp) < 0)) { min_timestamp = next_keyreq_time; found_timeout = 1; } } // Check timeout for sending heartbeat if (hbhost_count) { if (cmptimestamp(current_timestamp, next_hb_time) >= 0) { send_hb_request(listener, hb_hosts, hbhost_count, &next_hb_time, hb_interval, uid); done = 0; } else if ((!found_timeout) || (cmptimestamp(next_hb_time, min_timestamp) < 0)) { min_timestamp = next_hb_time; found_timeout = 1; } } } if (found_timeout) { tv = diff_timeval(min_timestamp, current_timestamp); return &tv; } else { return NULL; } }
int main(int argc, char *argv[]) { /* Packet Thread */ /* Initialize the mutex */ pthread_mutex_init(&m, 0); int i; char *lambda = "0.5"; char *mu = "0.35"; char *r = "1.5"; char *B = "10"; char *P = "3"; char *n = "20"; char *FILENAME = NULL; AVAILABLE = 0; DROPPED = 0; DROPPED_PKT = 0; TOTAL = 0; TOTAL_SERVED = 0; SERVER_DIE = 0; /* Read Options */ for(i=1;i<argc;i=i+2){ if (i%2!=0 && argv[i][0]=='-'){ if ((strcmp(argv[i]+1, "lambda") == 0) && ((i+1)<argc)){ lambda = argv[i+1]; if(check_num(lambda)== -1){ fprintf(stderr, "Value of lambda is not a number.\n"); exit(0); } continue; } else if ((strcmp(argv[i]+1, "mu") == 0) && ((i+1)<argc)){ mu = argv[i+1]; if(check_num(mu)== -1){ fprintf(stderr, "Value of mu is not a number.\n"); exit(0); } continue; } else if ((strcmp(argv[i]+1, "r") == 0) && ((i+1)<argc)){ r = argv[i+1]; if(check_num(r)== -1){ fprintf(stderr, "Value of r is not a number.\n"); exit(0); } continue; } else if ((strcmp(argv[i]+1, "B") == 0) && ((i+1)<argc)){ B = argv[i+1]; if(isNum(B)==-1){ fprintf(stderr, "Value of B is not a number.\n"); exit(0); } continue; } else if((strcmp(argv[i]+1, "P") == 0) && ((i+1)<argc)){ P = argv[i+1]; if(isNum(P) == -1){ fprintf(stderr, "Value of P is not a number.\n"); exit(0); } continue; } else if ((strcmp(argv[i]+1, "n") == 0) && ((i+1)<argc)){ n = argv[i+1]; if(isNum(n)==-1){ fprintf(stderr, "Value of n is not a number.\n"); exit(0); } continue; } else if ((strcmp(argv[i]+1, "t") == 0) && ((i+1)<argc)){ FILENAME = argv[i+1]; continue; } } fprintf(stderr, "Wrong command line argument\n"); exit(0); break; } /*Allocate memory to list*/ Q1 = malloc(sizeof(My402List)); Q2 = malloc(sizeof(My402List)); /*Initilialize the list*/ My402ListInit(Q1); My402ListInit(Q2); /* Block Signal from Main thread */ block_signal(); if(FILENAME!=NULL){ FILE *fp = fopen(FILENAME, "r"); if(fp==NULL){ perror("Error: Unable to open the file "); exit(0); } fclose(fp); } print_input(lambda, mu, FILENAME, r, B, P, n); /* Create packet thread */ fprintf(stdout, "\n"); /* Initialize the stats */ init_stats(); struct timeval current = diff_timeval(START_TIMEVAL, PKT_BEFORE); fprintf(stdout, "%08llu.%03ldms: emulation begins\n", toMilliSeconds(current), current.tv_usec%MILLI); /* Create threads */ create_packet_thread(lambda, mu, FILENAME, r, B, P, n); /* Print statistics */ //print_stats(); return(0); }
static inline int ping_v4(const char * hostname) { int sockfd; struct sockaddr_in address; icmp4_packet packet; int success = get_ipv4(hostname, IPPROTO_ICMP, &address); printf("ping "); print_host_v4(&address); printf("\n"); succeed_or_die(success, 0, create_raw_socket(AF_INET, SOCK_RAW, IPPROTO_ICMP, &sockfd)); succeed_or_die(success, 0, icmp4_packet_init(&packet, extract_ipv4(&address))); succeed_or_die(success, 0, icmp4_packet_set_length(&packet, sizeof packet)); int sent = 0; int i = 0; int gotten = 0; struct timeval wait_time = { 1, 0 }; long double min = 0.; long double max = 0.; long double sum = .0; struct timeval ping_start = { 0, 0 }; struct timeval ping_end = { 0, 0 }; gettimeofday(&ping_start, NULL); while (success == 0 && fin_des_temps == 1) { struct timeval start = { 0, 0 }; struct timeval end = { 0, 0 }; succeed_or_die(success, 0, icmp4_packet_set_echo_seq(&packet, i)); gettimeofday(&start, NULL); if (sendto(sockfd, &packet, sizeof packet, 0, (struct sockaddr *) &address, sizeof address) == sizeof packet) { sent++; icmp4_packet received; memset(&received, 0, sizeof received); int before = gotten; if (receive_icmp_v4(sockfd, &address, &wait_time, &received) == 0) { if (received.icmp_header.type == ICMP_ECHOREPLY && received.icmp_header.un.echo.sequence == i && received.icmp_header.un.echo.id == packet.icmp_header.un.echo.id ) { gotten++; gettimeofday(&end, NULL); struct timeval diff = diff_timeval(start, end); long double rtt = extract_time(diff); update_statistics(&min, &max, &sum, rtt, gotten, before); print_received(&received, &address, rtt); if (rtt > sum / gotten * 2 || rtt < sum / gotten / 2) success = -1; } } if ((float) gotten / sent < 0.7) success = -1; } i++; sleep(1); } gettimeofday(&ping_end, NULL); struct timeval total = diff_timeval(ping_start, ping_end); print_ping_statistics(sent, gotten, min, max, sum, total, &address); return success; }
/** * Sends a FILEINFO_ACK in response to a FILEINFO */ void send_fileinfo_ack(struct group_list_t *group, int restart) { unsigned char *buf, *encrypted, *outpacket; struct uftp_h *header; struct fileinfoack_h *fileinfo_ack; struct timeval now, send_time; unsigned int payloadlen; int enclen; buf = safe_calloc(MAXMTU, 1); header = (struct uftp_h *)buf; fileinfo_ack = (struct fileinfoack_h *)(buf + sizeof(struct uftp_h)); payloadlen = sizeof(struct fileinfoack_h); set_uftp_header(header, FILEINFO_ACK, group); fileinfo_ack->func = FILEINFO_ACK; fileinfo_ack->hlen = sizeof(struct fileinfoack_h) / 4; fileinfo_ack->file_id = htons(group->file_id); if (restart) { fileinfo_ack->flags |= FLAG_PARTIAL; } gettimeofday(&now, NULL); if (cmptimestamp(now, group->last_server_rx_ts) <= 0) { send_time = group->last_server_ts; } else { send_time = add_timeval(group->last_server_ts, diff_timeval(now, group->last_server_rx_ts)); } fileinfo_ack->tstamp_sec = htonl((uint32_t)send_time.tv_sec); fileinfo_ack->tstamp_usec = htonl((uint32_t)send_time.tv_usec); if (group->keytype != KEY_NONE) { encrypted = NULL; if (!encrypt_and_sign(buf, &encrypted, payloadlen, &enclen, group->keytype, group->groupkey, group->groupsalt,&group->ivctr, group->ivlen, group->hashtype, group->grouphmackey, group->hmaclen, group->sigtype, group->keyextype, group->client_privkey, group->client_privkeylen)) { glog0(group, "Error encrypting FILEINFO_ACK"); free(buf); return; } outpacket = encrypted; payloadlen = enclen; } else { encrypted = NULL; outpacket = buf; } payloadlen += sizeof(struct uftp_h); if (nb_sendto(listener, outpacket, payloadlen, 0, (struct sockaddr *)&(group->replyaddr), family_len(group->replyaddr)) == SOCKET_ERROR) { gsockerror(group, "Error sending FILEINFO_ACK"); } else { glog2(group, "FILEINFO_ACK sent"); } glog3(group, "send time: %d.%06d", send_time.tv_sec, send_time.tv_usec); free(encrypted); free(buf); }
/** * Sends a REGISTER message in response to an ANNOUNCE or on timeout when * waiting for a KEYINFO or REG_CONF. If the register timeout expired, abort. */ void send_register(struct group_list_t *group) { struct uftp_h *header; struct register_h *reg; unsigned char *buf, *keydata; struct timeval now, send_time; unsigned int len, meslen; union key_t key; gettimeofday(&now, NULL); if (cmptimestamp(now, group->expire_time) >= 0) { glog1(group, "Registration unconfirmed by server"); send_abort(group, "Registration unconfirmed"); return; } buf = safe_calloc(MAXMTU, 1); header = (struct uftp_h *)buf; reg = (struct register_h *)(buf + sizeof(struct uftp_h)); keydata = (unsigned char *)reg + sizeof(struct register_h); set_uftp_header(header, REGISTER, group); reg->func = REGISTER; if (group->keytype != KEY_NONE) { memcpy(reg->rand2, group->rand2, RAND_LEN); if (group->keyextype == KEYEX_RSA) { if (has_proxy) { key = proxy_pubkey; } else { key = group->server_pubkey; } if (!RSA_encrypt(key.rsa, group->premaster, group->premaster_len, keydata, &len)) { glog0(group, "Error encrypting premaster secret"); send_abort(group, "Error encrypting premaster secret"); free(buf); return; } } else { uint16_t keylen; if (!export_EC_key(group->client_dhkey.ec, keydata, &keylen)) { glog0(group, "Error exporting ECDH public key"); send_abort(group, "Error exporting ECDH public key"); free(buf); return; } len = keylen; } reg->keyinfo_len = htons(len); } else { len = 0; } gettimeofday(&now, NULL); if (cmptimestamp(now, group->last_server_rx_ts) <= 0) { send_time = group->last_server_ts; } else { send_time = add_timeval(group->last_server_ts, diff_timeval(now, group->last_server_rx_ts)); } reg->tstamp_sec = htonl((uint32_t)send_time.tv_sec); reg->tstamp_usec = htonl((uint32_t)send_time.tv_usec); reg->hlen = (sizeof(struct register_h) + len) / 4; meslen = sizeof(struct uftp_h) + (reg->hlen * 4); if (nb_sendto(listener, buf, meslen, 0, (struct sockaddr *)&(group->replyaddr), family_len(group->replyaddr)) == SOCKET_ERROR) { gsockerror(group, "Error sending REGISTER"); } else { glog2(group, "REGISTER sent"); } glog3(group, "send time: %d.%06d", send_time.tv_sec, send_time.tv_usec); set_timeout(group, 0); if (group->client_auth) { send_client_key(group); } free(buf); }
static si_t deal_with_mouse(struct input_device * self, struct list* msg_list) { union message msg; int get_msg_res; if(0 > (get_msg_res=basic_mouse(self, &msg))) { EGUI_PRINT_ERROR("failed to get mouse msg"); return -1; } if(1==get_msg_res) return 0; list_push_back(msg_list, &msg, sizeof(union message)); if(msg.mouse.type == MESSAGE_TYPE_MOUSE_PRESS) { /* 更改鼠标各个键的状态 */ if(msg.mouse.code == INPUT_CODE_MOUSE_L_KEY) { mouse_click.l_key = 1; } else if(msg.mouse.code == INPUT_CODE_MOUSE_M_KEY) { mouse_click.m_key = 1; } else if(msg.mouse.code == INPUT_CODE_MOUSE_R_KEY) { mouse_click.r_key = 1; } } else if(msg.mouse.type == MESSAGE_TYPE_MOUSE_RELEASE) { union message click_message; /* 更改鼠标各个键的状态 */ if(msg.mouse.code == INPUT_CODE_MOUSE_L_KEY) { mouse_click.l_key = 0; } else if(msg.mouse.code == INPUT_CODE_MOUSE_M_KEY) { mouse_click.m_key = 0; } else if(msg.mouse.code == INPUT_CODE_MOUSE_R_KEY) { mouse_click.r_key = 0; } /* 以前没有 */ if(mouse_click.has_previous_click == 0) { mouse_click.has_previous_click = 1; mouse_click.previous_click_key = msg.mouse.code; mouse_previous_click_time = msg.mouse.time; memcpy(&click_message, &msg, sizeof(union message)); click_message.mouse.type = MESSAGE_TYPE_MOUSE_SINGLE_CLICK; list_push_back(msg_list, &click_message, sizeof(union message)); } /* 以前有过 */ else if(mouse_click.has_previous_click == 1) { /* 两次的键一致 */ if(mouse_click.previous_click_key == msg.mouse.code) { struct timeval difference = {0}; /* difference = basic->mouse.time - mouse_previous_click_time */ diff_timeval(&(msg.mouse.time),&mouse_previous_click_time, &difference); memcpy(&click_message, &msg, sizeof(union message)); /* 在规定的时间内 */ if(difference.tv_sec == 0 && difference.tv_usec < mouse_double_click_delay) { click_message.mouse.type = MESSAGE_TYPE_MOUSE_DOUBLE_CLICK; mouse_click.has_previous_click = 0; } else { click_message.mouse.type = MESSAGE_TYPE_MOUSE_SINGLE_CLICK; mouse_previous_click_time = msg.mouse.time; } list_push_back(msg_list, &click_message, sizeof(union message)); } /* 两次的键不一致 */ else { mouse_click.previous_click_key = msg.mouse.code; mouse_previous_click_time = msg.mouse.time; memcpy(&click_message, &msg, sizeof(union message)); click_message.mouse.type = MESSAGE_TYPE_MOUSE_SINGLE_CLICK; list_push_back(msg_list, &click_message, sizeof(union message)); } } } else if(msg.mouse.type == MESSAGE_TYPE_MOUSE_MOVE) { union message* msg_ptr = list_back(msg_list); if(mouse_click.l_key == 1) { /* INPUT_MODIFIER_BIT_SET(INPUT_MODIFIER_MASK_MOUSE_L_KEY, &(msg_ptr->mouse.mask)); */ msg_ptr->mouse.mask = INPUT_MODIFIER_MASK_MOUSE_L_KEY | msg_ptr->mouse.mask; } if(mouse_click.m_key == 1) { /* INPUT_MODIFIER_BIT_SET(INPUT_MODIFIER_MASK_MOUSE_M_KEY, &(msg_ptr->mouse.mask)); */ msg_ptr->mouse.mask = INPUT_MODIFIER_MASK_MOUSE_M_KEY | msg_ptr->mouse.mask; } if(mouse_click.r_key == 1) { /* INPUT_MODIFIER_BIT_SET(INPUT_MODIFIER_MASK_MOUSE_R_KEY, &(msg_ptr->mouse.mask)); */ msg_ptr->mouse.mask = INPUT_MODIFIER_MASK_MOUSE_R_KEY | msg_ptr->mouse.mask; } } return 0; }