comparison src/protocols/msn/servconn.c @ 13200:33bef17125c2

[gaim-migrate @ 15563] This is the soon-to-be-infamous nonblocking network activity patch that I've been working on. Feel free to yell at me if this makes you unhappy. committer: Tailor Script <tailor@pidgin.im>
author Daniel Atallah <daniel.atallah@gmail.com>
date Thu, 09 Feb 2006 04:17:56 +0000
parents 4e7ba55a1db2
children 8754a0fe2297
comparison
equal deleted inserted replaced
13199:d8f238864c88 13200:33bef17125c2
48 48
49 servconn->httpconn = msn_httpconn_new(servconn); 49 servconn->httpconn = msn_httpconn_new(servconn);
50 50
51 servconn->num = session->servconns_count++; 51 servconn->num = session->servconns_count++;
52 52
53 servconn->tx_buf = gaim_circ_buffer_new(MSN_BUF_LEN);
54 servconn->tx_handler = -1;
55
53 return servconn; 56 return servconn;
54 } 57 }
55 58
56 void 59 void
57 msn_servconn_destroy(MsnServConn *servconn) 60 msn_servconn_destroy(MsnServConn *servconn)
71 servconn->destroy_cb(servconn); 74 servconn->destroy_cb(servconn);
72 75
73 if (servconn->httpconn != NULL) 76 if (servconn->httpconn != NULL)
74 msn_httpconn_destroy(servconn->httpconn); 77 msn_httpconn_destroy(servconn->httpconn);
75 78
76 if (servconn->host != NULL) 79 g_free(servconn->host);
77 g_free(servconn->host); 80
81 gaim_circ_buffer_destroy(servconn->tx_buf);
82 if (servconn->tx_handler > 0)
83 gaim_input_remove(servconn->tx_handler);
78 84
79 msn_cmdproc_destroy(servconn->cmdproc); 85 msn_cmdproc_destroy(servconn->cmdproc);
80 g_free(servconn); 86 g_free(servconn);
81 } 87 }
82 88
179 servconn->connected = TRUE; 185 servconn->connected = TRUE;
180 186
181 /* Someone wants to know we connected. */ 187 /* Someone wants to know we connected. */
182 servconn->connect_cb(servconn); 188 servconn->connect_cb(servconn);
183 servconn->inpa = gaim_input_add(servconn->fd, GAIM_INPUT_READ, 189 servconn->inpa = gaim_input_add(servconn->fd, GAIM_INPUT_READ,
184 read_cb, data); 190 read_cb, data);
185 } 191 }
186 else 192 else
187 { 193 {
188 msn_servconn_got_error(servconn, MSN_SERVCONN_ERROR_CONNECT); 194 msn_servconn_got_error(servconn, MSN_SERVCONN_ERROR_CONNECT);
189 } 195 }
225 231
226 return TRUE; 232 return TRUE;
227 } 233 }
228 234
229 r = gaim_proxy_connect(session->account, host, port, connect_cb, 235 r = gaim_proxy_connect(session->account, host, port, connect_cb,
230 servconn); 236 servconn);
231 237
232 if (r == 0) 238 if (r == 0)
233 { 239 {
234 servconn->processing = TRUE; 240 servconn->processing = TRUE;
235 return TRUE; 241 return TRUE;
277 283
278 if (servconn->disconnect_cb != NULL) 284 if (servconn->disconnect_cb != NULL)
279 servconn->disconnect_cb(servconn); 285 servconn->disconnect_cb(servconn);
280 } 286 }
281 287
288 static void
289 servconn_write_cb(gpointer data, gint source, GaimInputCondition cond)
290 {
291 MsnServConn *servconn = data;
292 int ret, writelen;
293
294 writelen = gaim_circ_buffer_get_max_read(servconn->tx_buf);
295
296 if (writelen == 0) {
297 gaim_input_remove(servconn->tx_handler);
298 servconn->tx_handler = -1;
299 return;
300 }
301
302 ret = write(servconn->fd, servconn->tx_buf->outptr, writelen);
303
304 if (ret < 0 && errno == EAGAIN)
305 return;
306 else if (ret <= 0) {
307 msn_servconn_got_error(servconn, MSN_SERVCONN_ERROR_WRITE);
308 return;
309 }
310
311 gaim_circ_buffer_mark_read(servconn->tx_buf, ret);
312 }
313
282 size_t 314 size_t
283 msn_servconn_write(MsnServConn *servconn, const char *buf, size_t len) 315 msn_servconn_write(MsnServConn *servconn, const char *buf, size_t len)
284 { 316 {
285 size_t ret = FALSE; 317 size_t ret = 0;
286 318
287 g_return_val_if_fail(servconn != NULL, 0); 319 g_return_val_if_fail(servconn != NULL, 0);
288 320
289 if (!servconn->session->http_method) 321 if (!servconn->session->http_method)
290 { 322 {
291 switch (servconn->type) 323 if (servconn->tx_handler == -1) {
292 { 324 switch (servconn->type)
293 case MSN_SERVCONN_NS: 325 {
294 case MSN_SERVCONN_SB: 326 case MSN_SERVCONN_NS:
295 ret = write(servconn->fd, buf, len); 327 case MSN_SERVCONN_SB:
296 break; 328 ret = write(servconn->fd, buf, len);
329 break;
297 #if 0 330 #if 0
298 case MSN_SERVCONN_DC: 331 case MSN_SERVCONN_DC:
299 ret = write(servconn->fd, &buf, sizeof(len)); 332 ret = write(servconn->fd, &buf, sizeof(len));
300 ret = write(servconn->fd, buf, len); 333 ret = write(servconn->fd, buf, len);
301 break; 334 break;
302 #endif 335 #endif
303 default: 336 default:
304 ret = write(servconn->fd, buf, len); 337 ret = write(servconn->fd, buf, len);
305 break; 338 break;
339 }
340 } else {
341 ret = -1;
342 errno = EAGAIN;
343 }
344
345 if (ret < 0 && errno == EAGAIN)
346 ret = 0;
347 if (ret < len) {
348 if (servconn->tx_handler == -1)
349 servconn->tx_handler = gaim_input_add(
350 servconn->fd, GAIM_INPUT_WRITE,
351 servconn_write_cb, servconn);
352 gaim_circ_buffer_append(servconn->tx_buf, buf + ret,
353 len - ret);
306 } 354 }
307 } 355 }
308 else 356 else
309 { 357 {
310 ret = msn_httpconn_write(servconn->httpconn, buf, len); 358 ret = msn_httpconn_write(servconn->httpconn, buf, len);
330 servconn = data; 378 servconn = data;
331 session = servconn->session; 379 session = servconn->session;
332 380
333 len = read(servconn->fd, buf, sizeof(buf) - 1); 381 len = read(servconn->fd, buf, sizeof(buf) - 1);
334 382
335 if (len <= 0) 383 if (len < 0 && errno == EAGAIN)
384 return;
385 else if (len <= 0)
336 { 386 {
337 gaim_debug_error("msn", "servconn read error, len: %d error: %s\n", len, strerror(errno)); 387 gaim_debug_error("msn", "servconn read error, len: %d error: %s\n", len, strerror(errno));
338 msn_servconn_got_error(servconn, MSN_SERVCONN_ERROR_READ); 388 msn_servconn_got_error(servconn, MSN_SERVCONN_ERROR_READ);
339 389
340 return; 390 return;