- Timestamp:
- 03/05/08 22:25:56 (5 years ago)
- Location:
- lang/c/partty/trunk
- Files:
-
- 2 modified
-
multiplexer.cc (modified) (14 diffs)
-
multiplexer.h (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
lang/c/partty/trunk/multiplexer.cc
r7507 r7515 22 22 emtelnet((void*)this), 23 23 m_host_telnet(host_telnet), 24 m_enable_ws(false) 24 m_enable_ws(false), 25 write_waiting(false) 25 26 { 26 27 // use these options … … 259 260 if( fcntl(guest, F_SETFL, O_NONBLOCK) < 0 || 260 261 mpev.add(guest, mp::EV_READ | mp::EV_WRITE) < 0 ) { 261 // イベント待ちは readable or writableから始める262 // イベント待ちは書き込み待ち状態から始める 262 263 perror("guest connection failed"); 263 264 close(guest); … … 267 268 // 書き込み待ちバッファにSERVER_WELCOME_MESSAGEを加える 268 269 guest_set.data(guest).send(SERVER_WELCOME_MESSAGE, strlen(SERVER_WELCOME_MESSAGE), NULL); 270 // 書き込み待ちから始める 271 guest_set.data(guest).write_waiting = true; 269 272 num_guest++; 270 273 return 0; … … 301 304 if( num_guest > 0 ) { 302 305 char sbbuf[4]; 303 *((short*)sbbuf) = htons(m_host_telnet.get_ rows());304 *((short*)(sbbuf+2)) = htons(m_host_telnet.get_ cols());306 *((short*)sbbuf) = htons(m_host_telnet.get_cols()); 307 *((short*)(sbbuf+2)) = htons(m_host_telnet.get_rows()); 305 308 int n = 0; 306 309 for(int fd = 0; fd < INT_MAX; ++fd) { … … 312 315 } 313 316 } 317 m_host_telnet.ws_flush(); 314 318 } 315 319 if( !m_host_telnet.ilength ) { return 0; } … … 354 358 remove_guest(fd); 355 359 return 0; 356 } else if( writable ){357 // 書き込み可能guest -> host360 } else { 361 // guest -> host 358 362 filt_telnetd::buffer_t ibuf; 359 363 if( recv_filter(fd, shared_buffer, len, &ibuf) < 0 ) { … … 361 365 return 0; 362 366 } 363 // FIXME Hostが切断されたのかエラーが発生したのか区別できない 364 if( continued_blocking_write_all(host, ibuf.buf, ibuf.len) != ibuf.len ) { 365 throw io_error("host socket is broken"); 366 } 367 } 368 // read-only guestからの入力はそのまま捨てる 367 if( writable ) { 368 // FIXME Hostが切断されたのかエラーが発生したのか区別できない 369 if( continued_blocking_write_all(host, ibuf.buf, ibuf.len) != ibuf.len ) { 370 throw io_error("host socket is broken"); 371 } 372 } 373 // read-only guestからの入力はそのまま捨てる 374 } 369 375 } 370 376 if( event & mp::EV_WRITE ) { … … 372 378 filt_telnetd& srv( guest_set.data(fd) ); 373 379 ssize_t len = write(fd, srv.obuffer, srv.olength); 374 //if( srv.olength == 0 ) { return 0; } // olengthは0の可能性がある?375 380 if( len < 0 ) { 376 381 if( errno == EAGAIN || errno == EINTR ) { return 0; } … … 396 401 return 0; 397 402 } 403 srv.write_waiting = false; 398 404 srv.oclear(); 399 405 } … … 406 412 { 407 413 filt_telnetd& srv( guest_set.data(fd) ); 408 bool may_writable = srv.is_oempty();409 414 srv.recv(buf, len, ibuf, NULL); // recvしたときにもobufが発生する 410 415 srv.iclear(); // 呼び出し側はibufを確実に使い切らないといけない 411 if( may_writable) {412 // 書き込み待ち バッファが空だったので書き込めるかもしれない416 if( !srv.write_waiting ) { 417 // 書き込み待ち状態ではないので今すぐ書き込めるかもしれない 413 418 if( guest_try_write(fd, srv) < 0 ) { 414 419 remove_guest(fd, srv); … … 422 427 { 423 428 filt_telnetd& srv( guest_set.data(fd) ); 424 bool may_writable = srv.is_oempty();425 429 srv.send(buf, len, NULL); 426 if( may_writable) {427 // 書き込み待ち バッファが空だったので書き込めるかもしれない430 if( !srv.write_waiting ) { 431 // 書き込み待ち状態ではないので今すぐ書き込めるかもしれない 428 432 if( guest_try_write(fd, srv) < 0 ) { 429 433 remove_guest(fd, srv); … … 438 442 // 現在の書き込み待ちバッファにあるバッファを書き込んでみて、 439 443 // 全部書き込めたらそのまま、書き込めなかったら書き込み待ちにする 440 // 書き込みバッファが無かった状態から書き込み待ちバッファがある状態に 441 // 遷移したときにのみ、この関数を呼べる 442 if( srv.olength <= 0 ) { return 0; } 444 if( srv.olength == 0 || srv.write_waiting ) { return 0; } 443 445 ssize_t wlen = write(fd, srv.obuffer, srv.olength); 444 446 if( wlen < 0 && errno != EAGAIN && errno != EINTR ) { … … 457 459 return -1; 458 460 } 461 srv.write_waiting = true; 459 462 } else { 460 463 // 全部書き込めた … … 472 475 void MultiplexerIMPL::remove_guest(int fd, filt_telnetd& srv) 473 476 { 474 mpev.remove(fd, mp::EV_READ | (srv. is_oempty() ? 0 : mp::EV_WRITE));477 mpev.remove(fd, mp::EV_READ | (srv.write_waiting ? mp::EV_READ : 0)); 475 478 guest_set.reset(fd); 476 479 num_guest--; -
lang/c/partty/trunk/multiplexer.h
r7485 r7515 46 46 inline void iconsumed(size_t len); 47 47 inline void oconsumed(size_t len); 48 inline bool is_oempty(void) { return olength == 0; }49 inline bool is_iempty(void) { return ilength == 0; }50 48 inline void get_ibuffer(buffer_t* in); 51 49 inline void get_obuffer(buffer_t* out); … … 57 55 sender_telnetd& m_host_telnet; 58 56 bool m_enable_ws; 57 public: 58 bool write_waiting; 59 59 }; 60 60
![(please configure the [header_logo] section in trac.ini)](/share/chrome/site/your_project_logo.png)