📄 msginfo.c
字号:
#include <stdio.h>#include <string.h>#include <errno.h>#include <glib.h>#include "support.h"#include "interface.h"#include "common.h"static GList *message_list=NULL;GStaticMutex msglst_mutex = G_STATIC_MUTEX_INIT;static guint timer_id;static gint message_info_find_element(gconstpointer a,gconstpointer b) { message_info_t *msg_a,*msg_b; if ( (!a) || (!b) ) return -EINVAL; msg_a=(message_info_t *)a; msg_b=(message_info_t *)b; if (msg_a->seq_no == msg_b->seq_no) return 0; /* found */ return 1; /* Not found */}static intfree_message_entry(GList *entry){ message_info_t *this_msg; if (!entry) return -EINVAL; this_msg=entry->data; _assert(this_msg); dbg_out("Release seqno %d msg\n",this_msg->seq_no); free(this_msg->ipaddr); free(this_msg->ed_msg_string); dbg_out("Free: %x\n",(unsigned int)this_msg); g_slice_free(message_info_t,this_msg); message_list=g_list_remove_link(message_list,entry); g_list_free(entry); return 0;}intunregister_sent_message(int pktno){ GList *found; message_info_t srch_msg; dbg_out("Try to unregister %d\n",pktno); srch_msg.seq_no=pktno; g_static_mutex_lock(&msglst_mutex); found=g_list_find_custom (message_list,&srch_msg,message_info_find_element); if (found) { free_message_entry(found); } g_static_mutex_unlock(&msglst_mutex); return 0;}intregister_sent_message(const udp_con_t *con,const char *ipaddr,int pktno,const char *message,size_t len){ message_info_t *new_msg; message_info_t *update_msg; GList *found; message_info_t srch_msg; if ( (!con) || (!ipaddr) || (!message) ) return -EINVAL; dbg_out("register ipaddr=%s\n",ipaddr); srch_msg.seq_no=pktno; g_static_mutex_lock(&msglst_mutex); found=g_list_find_custom (message_list,&srch_msg,message_info_find_element); if (found) { g_assert_not_reached(); /* 既に存在する場合は, リトライ回数を減算(ここにはこないはず) */ _assert(found->data); update_msg=found->data; --(update_msg->retry_remains); dbg_out("pktno: %d remain:%d\n",pktno,update_msg->retry_remains); if (!(update_msg->retry_remains)) { free_message_entry(found); } g_static_mutex_unlock(&msglst_mutex); return 0; } g_static_mutex_unlock(&msglst_mutex); new_msg=g_slice_new(message_info_t); if (!new_msg) return -ENOMEM; memset(new_msg,0,sizeof(message_info_t)); new_msg->ed_msg_string=strdup(message); if (!new_msg->ed_msg_string) goto free_message_info; new_msg->ipaddr=strdup(ipaddr); if (!new_msg->ipaddr) goto free_message; new_msg->con=(udp_con_t *)con; new_msg->len=len; new_msg->seq_no=pktno; new_msg->retry_remains=MSG_INFO_MAX_RETRY; new_msg->first=TRUE; g_static_mutex_lock(&msglst_mutex); message_list=g_list_append(message_list,new_msg); g_static_mutex_unlock(&msglst_mutex); dbg_out("Add new message:%d %s\n",pktno,message); return 0; free_message: free(new_msg->ed_msg_string); free_message_info: dbg_out("Free: %x\n",(unsigned int)new_msg); g_slice_free(message_info_t,new_msg); return -ENOMEM;}static gboolean retry_message_handler(gpointer data) { retry_messages_once(); return TRUE; }intretry_messages_once(void){ int rc=0; GList *last; GList *entry; GList *retry_messages=NULL; message_info_t *this_msg; g_static_mutex_lock(&msglst_mutex); last=g_list_last(message_list); g_static_mutex_unlock(&msglst_mutex); if (!last) { return 0; } dbg_out("Try to re-send unsent messages.\n"); g_source_remove (timer_id); g_static_mutex_lock(&msglst_mutex); while((entry=g_list_first(message_list))) { if (entry->data) { this_msg=entry->data; if (this_msg->first) { this_msg->first=FALSE; } else { dbg_out("retry:%d seq:%d addr:%s port: %d\nmsg:\n%s\n", this_msg->retry_remains, this_msg->seq_no, this_msg->ipaddr, hostinfo_refer_ipmsg_port(), this_msg->ed_msg_string); /* * メッセージの再登録を避けるために, udp_send_messageを直接呼び出す. */ rc=udp_send_message(udp_con, this_msg->ipaddr, hostinfo_refer_ipmsg_port(), this_msg->ed_msg_string, this_msg->len); if (rc<0) { rc*=-1; err_out("Can not send: %s %d\n",strerror(rc),rc); }else{ --this_msg->retry_remains; } } if (!(this_msg->retry_remains)) { GtkWidget *dialog; GtkWidget *nameLabel; userdb_t *user_info=NULL; char buffer[64]; dialog=GTK_WIDGET(create_sendFailDialog ()); if (!userdb_search_user_by_addr(this_msg->ipaddr,(const userdb_t **)&user_info)) { nameLabel=lookup_widget(dialog,"SendFailDialogUserLabel"); g_assert(nameLabel); snprintf(buffer,63,"%s@%s (%s)",user_info->nickname,user_info->group,user_info->host); buffer[63]='\0'; gtk_label_set_text(GTK_LABEL(nameLabel),buffer); g_assert(!destroy_user_info(user_info)); } if (gtk_dialog_run (GTK_DIALOG (dialog))==GTK_RESPONSE_OK) { this_msg->retry_remains=MSG_INFO_MAX_RETRY; dbg_out("reset retry count:seq=%d (remains:%d)\n", this_msg->seq_no,this_msg->retry_remains); this_msg->first=TRUE; /* 再登録 */ }else{ dbg_out("Free:seq=%d\n", this_msg->seq_no); free_message_entry(entry); gtk_widget_destroy (dialog); continue; } gtk_widget_destroy (dialog); } message_list=g_list_remove_link(message_list,entry); retry_messages=g_list_concat(retry_messages,entry); } } message_list=g_list_concat(message_list,retry_messages); g_static_mutex_unlock(&msglst_mutex); timer_id=g_timeout_add(MSG_INFO_RETRY_INTERVAL,retry_message_handler,NULL); return 0;}intinit_message_info_manager(void){ dbg_out("Start retry handler\n"); timer_id=g_timeout_add(MSG_INFO_RETRY_INTERVAL,retry_message_handler,NULL); return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -