[질문] poll 함수에서 OUT 이벤트 사용과 관련하여 ..

febace의 이미지

아래와 같이 폴을 이용하여 소켓에 이벤트 체킹을 해보았습니다.

그런데, 문제는 저의 예상과 달리,

소켓 버퍼가 꽉 차 있는데도, 폴의 OUT 체크에서 쓰기 가능으로 나타납니다.

그 결과 write에서 EAGAIN 과 함께 리소스 템포랠리 언어베일러블 이 납니다.

솔라리스 5.7에서 테스트 해보았고요,

이것이 폴만의 문제인지, 제 소스의 문제인지..
셀렉트로 바꾸면 잘 돌아갈지 궁금합니다.

     18 int
     19 polling(int timeout, d4g_hash_t *map)
     20 {
     21         int i, j, r, n;
     22         d4g_hash_iter_t *items;
     23         struct pollfd *pollfds;
     24 
     25         //printf("poll :\n");
     26         if (map == NULL) {
     27                 map = socket_map;
     28         }
     29         if (map == NULL)
     30                 return (0);
     31 
     32         /* make to reallor or ..something like that */
     33         n = d4g_hash_get_nelem(map);
     34 
     35         //printf("connected [%d]\n", n);
     36         pollfds = (struct pollfd *)calloc(n, sizeof(struct pollfd));
     37         if (pollfds == NULL) {
     38                 //perror("calloc failed\n");
     39                 exit (1);
     40         }
     41 
     42         /* race condition */
     43         for (items = d4g_hash_begin(map), i = 0;
     44                 items != NULL;
     45                 items = d4g_hash_iter_next(items), i++) {
     46 
     47                 //printf("[total:%d >= i:%d]\n", n,i);
     48 
     49                 pollfds[i].fd = ((sb_cham_t *)items->data)->socket->fd;
     50                 pollfds[i].events = 0;
     51                 pollfds[i].revents = 0;
     52
     53                 if (readable(((sb_cham_t *)items->data))) {
     54                         pollfds[i].events |= POLLIN;
     55                         //printf("Poll in oring[%d]\n", i);
     56                 }
     57 
     58                 if (writable(((sb_cham_t *)items->data))) {
     59                         //pollfds[i].events |= POLLWRNORM; 
     60                         pollfds[i].events |= POLLOUT;
     61                         //printf("Poll out oring[%d]\n", i);
     62                 }
     63         }
     64 
     65         /* i can be i - 1 */
     66         r = poll(pollfds, n, timeout);
     67         if (r < 0) { /* crictical error */
     68                 free(pollfds);
     69                 exit (0);
     70         }
     71 
     72         for (j = 0; j < n ; j++)
     73                 if (pollfds[j].revents & POLLIN) {
     74                         items = d4g_hash_lookup(map, &(pollfds[j].fd));
     75                         if (items == NULL)
     76                                 continue;
     77                         handle_read_event(((sb_cham_t *)items->data));
     78                 }
     79 
     80 
     81         for (j = 0; j < n ; j++)
     82                 //if (pollfds[j].revents & POLLWRNORM) {
     83                 if (pollfds[j].revents & POLLOUT) {
     84                         items = d4g_hash_lookup(map, &(pollfds[j].fd));
     85                         if (items == NULL)
     86                                 continue;
     87                         handle_write_event(((sb_cham_t *)items->data));
     88                 }
     89 
     90         free(pollfds);
     91         return (0);
     92 }
stoneshim의 이미지

이미 테스트 해보셨을지도 모르겠지만 select()도 동일한 결과를 나타냅니다.

제가 알기로는 accept()가 return한 fd에 대해서 writable event를 select()나 poll() 했을 경우, 항상 writable 로 return 합니다.

동일한 설명은 아니지만 solaris 의 poll manpage 중에 다음과 같은 설명이 있습니다.

Quote:
A file descriptor for a socket that is listening for connec-
tions will indicate that it is ready for reading, once con-
nections are available. A file descriptor for a socket that
is connecting asynchronously will indicate that it is ready
for writing, once a connection has been established.

우리 모두 리얼리스트가 되자. 그러나 가슴에 이룰 수 없는 꿈을 가지자

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.