首页 | 数据结构 | 文件列表 | 数据字段 | 全局定义

sendqueue.c

浏览该文件的文档。
00001 
00023 // START OF FILE
00024 /*****************************************************************************/
00025 #include "connection.h"         // GaimConnection
00026 #include "debug.h"              // gaim_debug
00027 #include "internal.h"           // _("get_text")
00028 #include "notify.h"             // gaim_notify
00029 #include "prefs.h"              // gaim_prefs_get_bool
00030 #include "request.h"            // gaim_request_action
00031 
00032 #include "header_info.h"        // cmd alias
00033 #include "qq_proxy.h"           // qq_proxy_write
00034 #include "sendqueue.h"
00035 
00036 #define QQ_RESEND_MAX               5   // max resend per packet
00037 
00038 typedef struct _gc_and_packet gc_and_packet;
00039 
00040 struct _gc_and_packet {
00041         GaimConnection *gc;
00042         qq_sendpacket *packet;
00043 };
00044 
00045 /*****************************************************************************/
00046 // Remove a packet with send_seq from sendqueue
00047 void qq_sendqueue_remove(qq_data * qd, guint16 send_seq)
00048 {
00049         GList *list;
00050         qq_sendpacket *p;
00051 
00052         g_return_if_fail(qd != NULL);
00053 
00054         list = qd->sendqueue;
00055         while (list != NULL) {
00056                 p = (qq_sendpacket *) (list->data);
00057                 if (p->send_seq == send_seq) {
00058                         qd->sendqueue = g_list_remove(qd->sendqueue, p);
00059                         g_free(p->buf);
00060                         g_free(p);
00061                         break;
00062                 }
00063                 list = list->next;
00064         }                       // while
00065 }                               // qq_sendqueue_remove
00066 
00067 /*****************************************************************************/
00068 // clean up sendqueue and free all contents
00069 void qq_sendqueue_free(qq_data * qd)
00070 {
00071         qq_sendpacket *p;
00072         gint i;
00073 
00074         i = 0;
00075         while (qd->sendqueue != NULL) {
00076                 p = (qq_sendpacket *) (qd->sendqueue->data);
00077                 qd->sendqueue = g_list_remove(qd->sendqueue, p);
00078                 g_free(p->buf);
00079                 g_free(p);
00080                 i++;
00081         }
00082         gaim_debug(GAIM_DEBUG_INFO, "QQ", "%d packets in sendqueue are freed!\n", i);
00083 }                               // qq_sendqueue_free
00084 
00085 /*****************************************************************************/
00086 // packet lost, agree to send again, (and will NOT prompt again)
00087 // it is removed only when ack-ed by server
00088 void _qq_send_again(gc_and_packet * gp)
00089 {
00090         GaimConnection *gc;
00091         qq_data *qd;
00092         qq_sendpacket *packet;
00093         GList *list;
00094 
00095         g_return_if_fail(gp != NULL && gp->gc != NULL && gp->packet != NULL);
00096         g_return_if_fail(gp->gc->proto_data != NULL);
00097 
00098         gc = gp->gc;
00099         packet = gp->packet;
00100         qd = (qq_data *) gc->proto_data;
00101 
00102         list = g_list_find(qd->sendqueue, packet);
00103         if (list != NULL) {
00104                 packet->resend_times = 0;
00105                 packet->sendtime = time(NULL);
00106                 qq_proxy_write(qd, packet->buf, packet->len);
00107         }
00108         g_free(gp);
00109 }                               // _qq_send_again
00110 
00111 /*****************************************************************************/
00112 // packet lost, do not send again
00113 void _qq_send_cancel(gc_and_packet * gp)
00114 {
00115         GaimConnection *gc;
00116         qq_data *qd;
00117         qq_sendpacket *packet;
00118         GList *list;
00119 
00120         g_return_if_fail(gp != NULL && gp->gc != NULL && gp->packet != NULL);
00121         g_return_if_fail(gp->gc->proto_data != NULL);
00122 
00123         gc = gp->gc;
00124         packet = gp->packet;
00125         qd = (qq_data *) gc->proto_data;
00126 
00127         list = g_list_find(qd->sendqueue, packet);
00128         if (list != NULL)
00129                 qq_sendqueue_remove(qd, packet->send_seq);
00130 
00131         g_free(gp);
00132 }                               // _qq_send_cancel
00133 
00134 /*****************************************************************************/
00135 gboolean qq_sendqueue_timeout_callback(gpointer data)
00136 {
00137         GaimConnection *gc;
00138         qq_data *qd;
00139         GList *list;
00140         qq_sendpacket *p;
00141         gc_and_packet *gp;
00142         time_t now;
00143         gint wait_time;
00144         gboolean need_action;
00145 
00146         gc = (GaimConnection *) data;
00147         qd = (qq_data *) gc->proto_data;
00148         now = time(NULL);
00149         list = qd->sendqueue;
00150 
00151         // empty queue, return TRUE so that timeout continues functioning
00152         if (qd->sendqueue == NULL)
00153                 return TRUE;
00154 
00155         while (list != NULL) {  // remove all packet whose resend_times == -1
00156                 p = (qq_sendpacket *) list->data;
00157                 if (p->resend_times == -1) {    // to remove
00158                         qd->sendqueue = g_list_remove(qd->sendqueue, p);
00159                         g_free(p->buf);
00160                         g_free(p);
00161                         list = qd->sendqueue;
00162                 } else
00163                         list = list->next;
00164         }                       // while list
00165 
00166         list = qd->sendqueue;
00167         while (list != NULL) {
00168                 p = (qq_sendpacket *) list->data;
00169                 if (p->resend_times >= QQ_RESEND_MAX) {
00170                         if (p->resend_times == QQ_RESEND_MAX) { // reach max
00171                                 switch (p->cmd) {
00172                                 case QQ_CMD_KEEP_ALIVE:
00173                                         if (qd->logged_in) {
00174                                                 gaim_debug(GAIM_DEBUG_ERROR, "QQ", "Connection lost!\n");
00175                                                 gaim_connection_error(gc, _("Connection lost!"));
00176                                                 qd->logged_in = FALSE;
00177                                         }       // if logged_in
00178                                         p->resend_times = -1;
00179                                         break;
00180                                 case QQ_CMD_LOGIN:
00181                                         if (!qd->logged_in)     // cancel logging progress
00182                                                 gaim_connection_error(gc, _("Login failed, no reply!"));
00183                                         p->resend_times = -1;
00184                                         break;
00185                                 case QQ_CMD_UPDATE_INFO:
00186                                         gaim_notify_error(gc, NULL,
00187                                                           _("Connection timeout!"), _("User info is not updated"));
00188                                         p->resend_times = -1;
00189                                         break;
00190                                 default:{
00191                                                 need_action =
00192                                                     gaim_prefs_get_bool("/plugins/prpl/qq/prompt_for_missing_packet");
00193                                                 if (!need_action)
00194                                                         p->resend_times = -1;   // it will be removed next time
00195                                                 else {  // prompt for action
00196                                                         gp = g_new0(gc_and_packet, 1);
00197                                                         gp->gc = gc;
00198                                                         gp->packet = p;
00199                                                         gaim_request_action
00200                                                             (gc, NULL,
00201                                                              _
00202                                                              ("Send packet"),
00203                                                              _
00204                                                              ("Packets lost, send again?"),
00205                                                              0, gp, 2,
00206                                                              _("Send"),
00207                                                              G_CALLBACK
00208                                                              (_qq_send_again),
00209                                                              _("Cancel"), G_CALLBACK(_qq_send_cancel));
00210                                                         p->resend_times++;      // will send once more, but only once
00211                                                 }       // if !need_action
00212                                         }       // default
00213                                 }       // switch
00214                         }       // resend_times == QQ_RESEND_MAX
00215                 } else {        // resend_times < QQ_RESEND_MAX, so sent it again
00216                         wait_time = (gint) (QQ_SENDQUEUE_TIMEOUT / 1000);
00217                         if (difftime(now, p->sendtime) > (wait_time * (p->resend_times + 1))) {
00218                                 qq_proxy_write(qd, p->buf, p->len);
00219                                 p->resend_times++;
00220                                 gaim_debug(GAIM_DEBUG_INFO,
00221                                            "QQ", "<<< [%05d] send again for %d times!\n", p->send_seq, p->resend_times);
00222                         }       // if difftime
00223                 }               // if resend_times >= QQ_RESEND_MAX            
00224                 list = list->next;
00225         }                       // whiile list
00226         return TRUE;            // if we return FALSE, the timeout callback stops functioning
00227 }                               // qq_sendqueue_timeout_callback
00228 
00229 /*****************************************************************************/
00230 // END OF FILE

Generated at Mon May 8 15:41:24 2006 for OpenQ by  doxygen 1.4.4