Linux non-blocking IO (eight) uses Epoll to re-implement non-blocking back-firing servers

Source: Internet
Author: User
Tags epoll

This article does not have much content, mainly is several previously mentioned note points:

One is that Epoll's FD needs reloading. We keep the tcp_connection_t pointer in the array, so we reload the FD listener event based on this array.

//Reload the epoll of FD in the monitor event        inti;  for(i =0; i < events_size; ++i) {if(Connsets[i]! =NULL) {                intFD = i;//FDtcp_connection_t *pt = connsets[i];//TCP Connuint32_tEvent=0; if(Buffer_is_readable (&pt->buffer_)) Event|=kwriteevent; if(Buffer_is_writeable (&pt->buffer_)) Event|=kreadevent; //Reset Listener EventsEPOLL_MOD_FD (EPOLLFD, FD,Event); }        }

Second, when establishing a connection, the work to be done is:

1. Create a new tcp_connection_t structure, initialize

2. Add FD to Epoll, do not listen for any events

3. Add the tcp_connection_t pointer to the array.

The code is as follows:

//Establish a connectionintPEERFD = ACCEPT4 (LISTENFD, NULL, NULL, Sock_nonblock |sock_cloexec);if(PEERFD = =-1) Err_exit ("Accept4");//New TCP connectiontcp_connection_t *pt = (tcp_connection_t*) malloc (sizeof(tcp_connection_t)); Buffer_init (&pt->buffer_);//Place the TCP connection into the ConnsetsCONNSETS[PEERFD] =pt;epoll_add_fd (EPOLLFD, PEERFD,0);

When the connection is closed, you need:

// Close  = NULL;

Another point: We recorded the relationship between FD and Connsets, using the array subscript, in fact, we can also put the pointer in the Epoll data, which:

typedef Union EPOLL_DATA {   void        *ptr;    int           FD;   uint32_t     u32;   uint64_t     U64;} epoll_data_t; struct epoll_event {   uint32_t     events;       /*  */   epoll_data_t data        ; /* */};

For the data consortium, we no longer use FD, but we use PTR, which points to a tcp_connection_t pointer. However, we need to store FD in the tcp_connection_t data structure.

For the sake of brevity, the previous method is still used, and the reader can try it out on its own.

The complete code is as follows:

#define_gnu_source/* See Feature_test_macros (7) */#include<sys/socket.h>#include"sysutil.h"#include"Buffer.h"#include<assert.h>#include<sys/epoll.h>#defineEvents_size 1024typedefstruct{buffer_t buffer_;} tcp_connection_t;//represents a TCP connectiontcp_connection_t*connsets[events_size];//provides mappings from FD to TCP connectionsintMainintargcChar Const*argv[]) {    //Get listener FD    intLISTENFD = Tcp_server ("localhost",9981); //set the Listen FD to non-blockingActivate_nonblock (LISTENFD); //Initialize Connsets    intIX;  for(ix =0; IX < Events_size; ++ix) {Connsets[ix]=NULL; }    //Initialize Epoll    intEPOLLFD = Epoll_create1 (0);    EPOLL_ADD_FD (EPOLLFD, LISTENFD, kreadevent); structEpoll_event events[1024x768];  while(1)    {        //Reload the epoll of FD in the monitor event        inti;  for(i =0; i < events_size; ++i) {if(Connsets[i]! =NULL) {                intFD = i;//FDtcp_connection_t *pt = connsets[i];//TCP Connuint32_tEvent=0; if(Buffer_is_readable (&pt->buffer_)) Event|=kwriteevent; if(Buffer_is_writeable (&pt->buffer_)) Event|=kreadevent; //Reset Listener EventsEPOLL_MOD_FD (EPOLLFD, FD,Event); }        }        //epoll Monitoring FD        intNready = epoll_wait (EPOLLFD, events,1024x768, the); if(Nready = =-1) Err_exit ("epoll Wait"); Else if(Nready = =0) {printf ("Epoll timeout.\n"); Continue; }        //processing FD         for(i =0; i < Nready; ++i) {intFD =EVENTS[I].DATA.FD; uint32_t revents=events[i].events; if(FD = = LISTENFD)//Processing Listen FD            {                if(Revents &kreadrevent) {                    //Establish a connection                    intPEERFD = ACCEPT4 (LISTENFD, NULL, NULL, Sock_nonblock |sock_cloexec); if(PEERFD = =-1) Err_exit ("Accept4"); //New TCP connectiontcp_connection_t *pt = (tcp_connection_t*) malloc (sizeof(tcp_connection_t)); Buffer_init (&pt->buffer_); //Place the TCP connection into the ConnsetsCONNSETS[PEERFD] =pt; EPOLL_ADD_FD (EPOLLFD, PEERFD,0); }            }            Else //processing of FD for ordinary customers            {                //Remove the pointertcp_connection_t *pt =CONNSETS[FD]; Assert (PT!=NULL); if(Revents &kreadrevent) {                    if(Buffer_read (&pt->buffer_, fd) = =0)                    {                        //Closeepoll_del_fd (EPOLLFD, FD);                        Close (FD);                        Free (PT); CONNSETS[FD]=NULL; Continue;//continue the next cycle                    }                 }                if(Revents &kwriterevent) {Buffer_write (&pt->Buffer_, FD);    }}}} close (LISTENFD); return 0;}

The following uses the Epoll et pattern.

Linux non-blocking IO (eight) uses Epoll to re-implement non-blocking back-firing servers

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.