Hypercell ein ] Hypercell aus ] Zeige Navigation ] Verstecke Navigation ]
c++.net  
   

Die mobilen Seiten von c++.net:
https://m.c-plusplus.net

  
C++ Forum :: Linux/Unix ::  Epoll bleibt hängen     Zeige alle Beiträge auf einer Seite Auf Beitrag antworten
Autor Nachricht
Tuxist
Mitglied

Benutzerprofil
Anmeldungsdatum: 18.02.2007
Beiträge: 149
Beitrag Tuxist Mitglied 09:54:37 10.09.2016   Titel:   Epoll bleibt hängen            Zitieren

Moin,

habe epoll interface implementiert in meinen kleinen http server leider bleibt chrome beim recv hängen so weit ich das verstehe muss bei connection close etwas schief gehen da chrome mit mehreren verbindungen arbeitet.

gdb ausgabe:
Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
HTTP Note: switch to recv mode!
HTTP Note: switch to recv m^C
Program received signal SIGINT, Interrupt.
0x00007ffff756ca10 in __write_nocancel () at ../sysdeps/unix/syscall-template.S:84
84      ../sysdeps/unix/syscall-template.S: Datei oder Verzeichnis nicht gefunden.
(gdb) bt
#0  0x00007ffff756ca10 in __write_nocancel () at ../sysdeps/unix/syscall-template.S:84
#1  0x00007ffff74eeb2f in _IO_new_file_write (f=0x7ffff783a620 <_IO_2_1_stdout_>, data=0x61f360, n=33)
    at fileops.c:1263
#2  0x00007ffff74f0339 in new_do_write (to_do=33,
    data=0x61f360 "HTTP Note: switch to recv mode!\r\nermination not found\r\n", fp=0x7ffff783a620 <_IO_2_1_stdout_>)
    at fileops.c:518
#3  _IO_new_do_write (fp=0x7ffff783a620 <_IO_2_1_stdout_>,
    data=0x61f360 "HTTP Note: switch to recv mode!\r\nermination not found\r\n", to_do=33) at fileops.c:494
#4  0x00007ffff74ef3ad in _IO_new_file_xsputn (f=0x7ffff783a620 <_IO_2_1_stdout_>, data=<optimized out>, n=33)
    at fileops.c:1331
#5  0x00007ffff74c44cb in _IO_vfprintf_internal (s=0x7ffff783a620 <_IO_2_1_stdout_>, format=<optimized out>,
    ap=ap@entry=0x7fffffffd3e8) at vfprintf.c:1632
#6  0x00007ffff74cb849 in __printf (format=<optimized out>) at printf.c:33
#7  0x0000000000405091 in libhttppp::HTTPException::ErrorTemplate<char const*, char const*> (this=0x61ef00,
    type=0x61f007, buffer=0x61ef08 "HTTP Note: switch to recv mode!\r\n", printstyle=0x408f69 "HTTP Note: %s\r\n",
    message=0x4095fd "switch to recv mode!") at /home/jan/projects/libhttppp/libhttppp/test/../src/exception.h:109
#8  0x0000000000404d51 in libhttppp::HTTPException::Note (this=0x61ef00, msg=0x4095fd "switch to recv mode!")
    at /home/jan/projects/libhttppp/libhttppp/test/../src/exception.h:80
#9  0x000000000040730f in libhttppp::Queue::Queue (this=0x61edd0, socket=0x61ec20)
    at /home/jan/projects/libhttppp/libhttppp/src/queues/epoll.cpp:134
#10 0x0000000000406b88 in libhttppp::HttpD::runDaemon (this=0x7fffffffd800)
    at /home/jan/projects/libhttppp/libhttppp/src/httpd.cpp:74
#11 0x0000000000404f83 in HttpConD::HttpConD (this=0x7fffffffd800, argc=4, argv=0x7fffffffde28)
    at /home/jan/projects/libhttppp/libhttppp/test/httpcon.cpp:51
#12 0x0000000000404beb in main (argc=4, argv=0x7fffffffde28)
    at /home/jan/projects/libhttppp/libhttppp/test/httpcon.cpp:60


https://github.com/Tuxist/libhttppp

C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
/*******************************************************************************
Copyright (c) 2014, Jan Koester jan.koester@gmx.net
All rights reserved.
 
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
    * Redistributions of source code must retain the above copyright
      notice, this list of conditions and the following disclaimer.
    * Redistributions in binary form must reproduce the above copyright
      notice, this list of conditions and the following disclaimer in the
      documentation and/or other materials provided with the distribution.
    * Neither the name of the <organization> nor the
      names of its contributors may be used to endorse or promote products
      derived from this software without specific prior written permission.
 
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*******************************************************************************/


#include <fcntl.h>

#include <sys/epoll.h>
#include <cstdlib>
#include <config.h>
#include <errno.h>

#define READEVENT 0

#define SENDEVENT 1

#include "../queue.h"

 
using namespace libhttppp;
 
Queue::Queue(ServerSocket *socket) : ConnectionPool(socket) {
  struct epoll_event *events;
  struct epoll_event  event = {0};
  events = new epoll_event[(socket->getMaxconnections()*sizeof(struct epoll_event))];
  for(int i=0; i<socket->getMaxconnections(); i++)
    events[i].data.fd = -1;
  int epollfd = epoll_create(socket->getMaxconnections());
 
  if (epollfd == -1){
    _httpexception.Cirtical("can't create epoll");
    throw _httpexception;
  }
 
  event.events = EPOLLIN | EPOLLRDHUP;
  event.data.fd = socket->getSocket();
  if (epoll_ctl(epollfd, EPOLL_CTL_ADD, socket->getSocket(), &event) < 0){
    _httpexception.Cirtical("can't create epoll");
    throw _httpexception;
  }
 
  for(;;){
    int n = epoll_wait(epollfd, events, socket->getMaxconnections(), EPOLLWAIT);
    for(int i=0; i<n; i++) {
      Connection *curcon=NULL;
      if(events[i].data.fd == socket->getSocket()) {
        try{
          /*will create warning debug mode that normally because the check already connection
           * with this socket if getconnection throw they will be create a new one
           */

      curcon=addConnection();
      ClientSocket *clientsocket=curcon->getClientSocket();
      clientsocket->setnonblocking();
          event.data.fd =_ServerSocket->acceptEvent(clientsocket);
          event.events = EPOLLIN | EPOLLRDHUP;
         
          if(epoll_ctl(epollfd, EPOLL_CTL_ADD, event.data.fd, &event)==-1 && errno==EEXIST)
            epoll_ctl(epollfd, EPOLL_CTL_MOD, events[i].data.fd, &event);
        }catch(HTTPException &e){
          if(e.isCritical())
            throw e;
        }
        continue;
      }else{
    curcon=getConnection(events[i].data.fd);
      }
     
      if(events[i].events & EPOLLIN){
          try{
            char buf[BLOCKSIZE];
            int rcvsize=_ServerSocket->recvData(curcon->getClientSocket(),buf,BLOCKSIZE);
            printf("recvsize: %d\n",rcvsize);
        if(rcvsize==-1){
               if (errno == EAGAIN)
                 continue;
               else
                 goto CloseConnection;
            }
            curcon->addRecvQueue(buf,rcvsize);
            RequestEvent(curcon);
            if(curcon->getSendData()){
              event.events = EPOLLOUT | EPOLLRDHUP;
              epoll_ctl(epollfd, EPOLL_CTL_MOD, events[i].data.fd, &event);
          _httpexception.Note("switch to send mode!");
            }
          }catch(HTTPException &e){
            if(e.isCritical()){
              throw e;
            }
            if(e.isError())
             goto CloseConnection;
          }
      }
     
      if(events[i].events & EPOLLOUT) {
        try{
          if(curcon && curcon->getSendData()){
            ssize_t sended=_ServerSocket->sendData(curcon->getClientSocket(),
                                                   (void*)curcon->getSendData()->getData(),
                                                    curcon->getSendData()->getDataSize());
            if(sended==-1){
              _httpexception.Note("Sending Failed");
              if (errno == EAGAIN){
                continue;
              }else{
        curcon->cleanSendData();
                goto CloseConnection;
          }
            }else{
              curcon->resizeSendQueue(sended);
            }
          }else{
              event.events = EPOLLIN | EPOLLRDHUP;
              epoll_ctl(epollfd, EPOLL_CTL_MOD, events[i].data.fd, &event);
          _httpexception.Note("switch to recv mode!");
          }
        }catch(HTTPException &e){
           goto CloseConnection;
        }
      }
     
      if(events[i].events & EPOLLRDHUP || events[i].events & EPOLLERR) {
          CloseConnection:
            try{
              delConnection(curcon);
              epoll_ctl(epollfd, EPOLL_CTL_DEL, events[i].data.fd, &event);
          _httpexception.Note("Connection shutdown!");
          continue;
            }catch(HTTPException &e){
              _httpexception.Note("Can't do Connection shutdown!");
            }
          ;
      }
    }
  }
  delete events;
   
}
 
Queue::~Queue(){
 
}


Zuletzt bearbeitet von Tuxist am 15:48:21 10.09.2016, insgesamt 3-mal bearbeitet
dachschaden
Mitglied

Benutzerprofil
Anmeldungsdatum: 06.12.2014
Beiträge: 938
Beitrag dachschaden Mitglied 11:51:30 10.09.2016   Titel:              Zitieren

Zunächst mal implementierst du nicht epoll, sondern du verwendest das epoll-Interface.

Und ansonsten: ist das dein Scheißernst? Du klatschst einfach zwei Blöcke Code hin, sagst nicht mal wage "Hier irgendwo muss der Fehler sein", und erwartest, dass sich die Leute noch deinen Code herunterladen und ein Nicht-Standard-Buildsystem verwenden, um deinen Server zu bauen (brauchst du cmake für irgendwas besonderes? Kann ich mir nicht vorstellen). Dann baue ich den Server zähneknirschend, aber dieses cmake sagt mir nicht, wo er gebaut hat. Ich habe auch ohne Anleitung keinen Bock, danach zu suchen. Nee, so läuft das nicht.

_________________
Meine sämtlichen Posts sind gleichzeitig als Provokation gemeint, mich in Frage zu stellen. Ich erwarte, dass man mich in Frage stellt und auch korrigiert.
The only valid measurement of code quality: WTFs/minute
Tuxist
Mitglied

Benutzerprofil
Anmeldungsdatum: 18.02.2007
Beiträge: 149
Beitrag Tuxist Mitglied 12:28:04 10.09.2016   Titel:              Zitieren

cmake baut in dem Verzeichnis von dem aus cmake getstartet wurden ist.

mkdir libhttppp/build
cd build
cmake ../
make

dann starten einer demo:

./test/httpcon --httpaddr=0.0.0.0 --httpport=8080 --rootpath=/tmp
Tuxist
Mitglied

Benutzerprofil
Anmeldungsdatum: 18.02.2007
Beiträge: 149
Beitrag Tuxist Mitglied 16:37:23 25.09.2016   Titel:              Zitieren

habe jetzt auf epollet umgestellt hängt jetzt aber bei recv und somit läuft der loop nicht durch die sockets nonblock gesetzt.

C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
        for(;;){
              char buf[BLOCKSIZE];
              int rcvsize=_ServerSocket->recvData(curcon->getClientSocket(),buf,BLOCKSIZE);
              printf("recvsize: %d\n",rcvsize);
          if(rcvsize==-1){
                if (errno == EAGAIN){
                  break;
        }else{
                  goto CloseConnection;
        }
              }else if(rcvsize==0){
        break;
          }
              curcon->addRecvQueue(buf,rcvsize);
        }
Tuxist
Mitglied

Benutzerprofil
Anmeldungsdatum: 18.02.2007
Beiträge: 149
Beitrag Tuxist Mitglied 13:43:04 04.10.2016   Titel:              Zitieren

habe es hin bekommen war blöder fehler setnonblocking aus veresehen vor accept event gesetzt.


Zuletzt bearbeitet von Tuxist am 14:45:19 04.10.2016, insgesamt 2-mal bearbeitet
5cript
Mitglied

Benutzerprofil
Anmeldungsdatum: 14.03.2009
Beiträge: 1948
Beitrag 5cript Mitglied 18:39:39 23.12.2016   Titel:              Zitieren

@dachschaden. Also cmake können ist eigentlich pflichtprogramm ^^.

_________________
http://assets.amuniversal ....... 067f90134cb84005056a9545d
dachschaden
Mitglied

Benutzerprofil
Anmeldungsdatum: 06.12.2014
Beiträge: 938
Beitrag dachschaden Mitglied 23:10:34 02.02.2017   Titel:              Zitieren

5cript schrieb:
@dachschaden. Also cmake können ist eigentlich pflichtprogramm ^^.


cmake ist das schlechteste Build-System, das ich je gesehen habe.

Zitat:
Hey, lasst uns eine CMakeCache.txt erstellen, die nicht aktualisiert wird, wenn der User eigene Bibliotheksverzeichnisse angibt, sodass wir auf keinen Fall speziell für diese Architektur kompilierte Binaries finden. Soll der Nutzer doch raten, dass diese Datei erst gelöscht werden muss, damit wir seine neuen Optionen anerkennen.


Oder:

Zitat:
Hey, lasst uns -DCMAKE_INSTALL_PREFIX manchmal nicht zum Makefile durchreichen, sodass der User am Ende make install aufruft und die ganze Scheiße in einem Verzeichnis installiert wird, in dass sie nicht rein soll.


Oder, der Kracher:

Zitat:
Hey, lasst uns irgendwelche Spastis nicht dazu zwingen, ein verdammtes make uninstall anzulegen, damit der User, wenn er denn merkt, dass ihr's nicht hinbekommen habt, -DCMAKE_INSTALL_PREFIX durchzureichen, es auch nicht wieder automatisiert entfernen kann. Das soll der dann mal schön selbermachen woot LOL rofl


GNU Make ist nicht perfekt, aber es ist bei weitem besser als alles, was diese Hipster-Spacken von cmake je rausgebracht haben. Die haben's auf Lebenszeit bei mir verkackt mit ihrer unfertigen Gülle. Und dabei habe ich noch nicht mal eine Cross-Compilierung versucht *schauder*.

_________________
Meine sämtlichen Posts sind gleichzeitig als Provokation gemeint, mich in Frage zu stellen. Ich erwarte, dass man mich in Frage stellt und auch korrigiert.
The only valid measurement of code quality: WTFs/minute
C++ Forum :: Linux/Unix ::  Epoll bleibt hängen   Auf Beitrag antworten

Zeige alle Beiträge auf einer Seite




Nächstes Thema anzeigen
Vorheriges Thema anzeigen
Sie können Beiträge in dieses Forum schreiben.
Sie können auf Beiträge in diesem Forum antworten.
Sie können Ihre Beiträge in diesem Forum nicht bearbeiten.
Sie können Ihre Beiträge in diesem Forum nicht löschen.
Sie können an Umfragen in diesem Forum nicht mitmachen.

Powered by phpBB © 2001, 2002 phpBB Group :: FI Theme

c++.net ist Teilnehmer des Partnerprogramms von Amazon Europe S.à.r.l. und Partner des Werbeprogramms, das zur Bereitstellung eines Mediums für Websites konzipiert wurde, mittels dessen durch die Platzierung von Werbeanzeigen und Links zu amazon.de Werbekostenerstattung verdient werden kann.

Die Vervielfältigung der auf den Seiten www.c-plusplus.de, www.c-plusplus.info und www.c-plusplus.net enthaltenen Informationen ohne eine schriftliche Genehmigung des Seitenbetreibers ist untersagt (vgl. §4 Urheberrechtsgesetz). Die Nutzung und Änderung der vorgestellten Strukturen und Verfahren in privaten und kommerziellen Softwareanwendungen ist ausdrücklich erlaubt, soweit keine Rechte Dritter verletzt werden. Der Seitenbetreiber übernimmt keine Gewähr für die Funktion einzelner Beiträge oder Programmfragmente, insbesondere übernimmt er keine Haftung für eventuelle aus dem Gebrauch entstehenden Folgeschäden.