00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #ifdef HAVE_CONFIG_H
00014 # include <config.h>
00015 #endif
00016
00017
00018 #include "iomanager_l.h"
00019 #include "iolayer_l.h"
00020
00021 #include "i18n_l.h"
00022 #include <gwenhywfar/misc.h>
00023 #include <gwenhywfar/debug.h>
00024 #include <gwenhywfar/gui.h>
00025 #include <gwenhywfar/gwentime.h>
00026
00027 #include <assert.h>
00028
00029 #include <gnutls/gnutls.h>
00030
00031
00032
00033 static GWEN_IO_LAYER_LIST *ioLayerList=NULL;
00034
00035
00036
00037 int GWEN_Io_Manager_ModuleInit() {
00038 ioLayerList=GWEN_Io_Layer_List_new();
00039
00040 gnutls_global_init();
00041
00042 return 0;
00043 }
00044
00045
00046
00047 int GWEN_Io_Manager_ModuleFini() {
00048 if (ioLayerList) {
00049 GWEN_Io_Layer_List_free(ioLayerList);
00050 ioLayerList=NULL;
00051 }
00052
00053 gnutls_global_deinit();
00054
00055 return 0;
00056 }
00057
00058
00059
00060 int GWEN_Io_Manager_RegisterLayer(GWEN_IO_LAYER *io) {
00061 GWEN_IO_LAYER *p;
00062
00063
00064 p=GWEN_Io_Layer_List_First(ioLayerList);
00065 while(p) {
00066 if (p==io) {
00067 DBG_INFO(GWEN_LOGDOMAIN, "IO Layer %p already registered", (void*)io);
00068 return GWEN_ERROR_INVALID;
00069 }
00070 p=GWEN_Io_Layer_List_Next(p);
00071 }
00072
00073 GWEN_Io_Layer_List_Add(io, ioLayerList);
00074
00075 GWEN_Io_Layer_AddFlags(io, GWEN_IO_LAYER_FLAGS_REGISTERED);
00076 return 0;
00077 }
00078
00079
00080
00081 int GWEN_Io_Manager_UnregisterLayer(GWEN_IO_LAYER *io) {
00082 GWEN_IO_LAYER *p;
00083
00084
00085 p=GWEN_Io_Layer_List_First(ioLayerList);
00086 while(p) {
00087 if (p==io)
00088 break;
00089 p=GWEN_Io_Layer_List_Next(p);
00090 }
00091
00092 if (p!=io) {
00093 DBG_INFO(GWEN_LOGDOMAIN, "IO Layer %p not registered", (void*)io);
00094 return GWEN_ERROR_INVALID;
00095 }
00096
00097 GWEN_Io_Layer_SubFlags(io, GWEN_IO_LAYER_FLAGS_REGISTERED);
00098 GWEN_Io_Layer_List_Del(io);
00099
00100
00101 return 0;
00102 }
00103
00104
00105
00106 GWEN_IO_LAYER_WORKRESULT GWEN_Io_Manager_Work(void) {
00107 int anythingDone=0;
00108 int i;
00109
00110 for (i=0;i<10;i++) {
00111 GWEN_IO_LAYER *p;
00112 int somethingDone=0;
00113
00114 p=GWEN_Io_Layer_List_First(ioLayerList);
00115 while(p) {
00116 GWEN_IO_LAYER_WORKRESULT res;
00117
00118 res=GWEN_Io_Layer_WorkOnRequests(p);
00119 if (res==GWEN_Io_Layer_WorkResultOk)
00120 somethingDone=1;
00121
00122 p=GWEN_Io_Layer_List_Next(p);
00123 }
00124 if (somethingDone)
00125 anythingDone++;
00126 else
00127 break;
00128 }
00129
00130 return anythingDone?GWEN_Io_Layer_WorkResultOk:GWEN_Io_Layer_WorkResultBlocking;
00131 }
00132
00133
00134
00135 int GWEN_Io_Manager_Wait(int msecs, uint32_t guiid) {
00136 GWEN_IO_LAYER *p;
00137 GWEN_SOCKET_LIST2 *readSockets;
00138 GWEN_SOCKET_LIST2 *writeSockets;
00139 int rv;
00140
00141
00142 readSockets=GWEN_Socket_List2_new();
00143 writeSockets=GWEN_Socket_List2_new();
00144
00145 p=GWEN_Io_Layer_List_First(ioLayerList);
00146 while(p) {
00147 GWEN_Io_Layer_AddWaitingSockets(p, readSockets, writeSockets);
00148 p=GWEN_Io_Layer_List_Next(p);
00149 }
00150
00151 rv=GWEN_Gui_WaitForSockets(readSockets, writeSockets, guiid, msecs);
00152 GWEN_Socket_List2_free(writeSockets);
00153 GWEN_Socket_List2_free(readSockets);
00154
00155 if (rv) {
00156 if (rv!=GWEN_ERROR_EOF) {
00157 DBG_INFO(GWEN_LOGDOMAIN, "WAITFORSOCKETS: %d", rv);
00158 }
00159 }
00160
00161 return rv;
00162 }
00163
00164
00165
00166 int GWEN_Io_Manager_WaitForRequest(GWEN_IO_REQUEST *r, int msecs) {
00167 GWEN_TIME *t0;
00168 uint32_t progressId;
00169 uint64_t timeout;
00170 const char *s;
00171 GWEN_IO_LAYER_WORKRESULT res;
00172
00173 if (GWEN_Io_Request_GetStatus(r)==GWEN_Io_Request_StatusFinished) {
00174
00175 return 0;
00176 }
00177
00178 if (msecs==GWEN_TIMEOUT_NONE) {
00179
00180 DBG_INFO(GWEN_LOGDOMAIN, "No timeout, returning immediately");
00181 return GWEN_ERROR_TIMEOUT;
00182 }
00183
00184
00185 res=GWEN_Io_Manager_Work();
00186 if (GWEN_Io_Request_GetStatus(r)==GWEN_Io_Request_StatusFinished) {
00187 return 0;
00188 }
00189
00190
00191 t0=GWEN_CurrentTime();
00192 assert(t0);
00193
00194 if (msecs==GWEN_TIMEOUT_NONE ||
00195 msecs==GWEN_TIMEOUT_FOREVER)
00196 timeout=0;
00197 else
00198 timeout=msecs;
00199
00200 switch(GWEN_Io_Request_GetType(r)) {
00201 case GWEN_Io_Request_TypeConnect:
00202 s=I18N("Connecting...");
00203 break;
00204 case GWEN_Io_Request_TypeDisconnect:
00205 s=I18N("Disconnecting...");
00206 break;
00207 case GWEN_Io_Request_TypeRead:
00208 s=I18N("Reading...");
00209 break;
00210 case GWEN_Io_Request_TypeWrite:
00211 s=I18N("Writing...");
00212 break;
00213 default:
00214 s=I18N("Waiting for request to finish...");
00215 }
00216
00217 progressId=GWEN_Gui_ProgressStart(GWEN_GUI_PROGRESS_DELAY |
00218 GWEN_GUI_PROGRESS_ALLOW_EMBED |
00219 GWEN_GUI_PROGRESS_SHOW_PROGRESS |
00220 GWEN_GUI_PROGRESS_SHOW_ABORT,
00221 s,
00222 NULL,
00223 timeout,
00224 GWEN_Io_Request_GetGuiId(r));
00225
00226 for (;;) {
00227 int rv;
00228 int i;
00229 int shortTimeout=msecs;
00230
00231
00232 for (i=0; i<10000; i++) {
00233 if (GWEN_Io_Request_GetStatus(r)==GWEN_Io_Request_StatusFinished) {
00234
00235 GWEN_Gui_ProgressEnd(progressId);
00236 GWEN_Time_free(t0);
00237 return 0;
00238 }
00239 res=GWEN_Io_Manager_Work();
00240 if (res==GWEN_Io_Layer_WorkResultBlocking)
00241 break;
00242 if (res==GWEN_Io_Layer_WorkResultError) {
00243 DBG_INFO(GWEN_LOGDOMAIN, "IO error (res=%d)", res);
00244 GWEN_Gui_ProgressLog(progressId,
00245 GWEN_LoggerLevel_Error,
00246 I18N("IO error"));
00247 GWEN_Gui_ProgressEnd(progressId);
00248 GWEN_Time_free(t0);
00249 return GWEN_ERROR_IO;
00250 }
00251 }
00252
00253 if (msecs!=GWEN_TIMEOUT_FOREVER) {
00254 GWEN_TIME *t1;
00255 int d;
00256
00257
00258 t1=GWEN_CurrentTime();
00259 assert(t1);
00260 d=(int)GWEN_Time_Diff(t1, t0);
00261 GWEN_Time_free(t1);
00262 if (d>=msecs) {
00263 DBG_INFO(GWEN_LOGDOMAIN, "Timeout (%d>%d)", d, msecs);
00264 GWEN_Gui_ProgressEnd(progressId);
00265 GWEN_Time_free(t0);
00266 return GWEN_ERROR_TIMEOUT;
00267 }
00268
00269 shortTimeout=msecs-d;
00270 }
00271
00272
00273
00274
00275
00276 if (res!=GWEN_Io_Layer_WorkResultBlocking) {
00277
00278 DBG_WARN(GWEN_LOGDOMAIN, "Still working after %d loops, sleeping", i);
00279 GWEN_Socket_Select(NULL, NULL, NULL, GWEN_GUI_CPU_TIMEOUT);
00280 }
00281 else {
00282
00283 rv=GWEN_Io_Manager_Wait(shortTimeout, progressId);
00284 if (rv!=0 && rv!=GWEN_ERROR_TIMEOUT) {
00285 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
00286 GWEN_Gui_ProgressLog(progressId,
00287 GWEN_LoggerLevel_Error,
00288 I18N("IO error"));
00289 GWEN_Gui_ProgressEnd(progressId);
00290 GWEN_Time_free(t0);
00291 return rv;
00292 }
00293 }
00294 }
00295 }
00296
00297
00298
00299
00300
00301