/[hydra]/hydra/src/hic.c
ViewVC logotype

Diff of /hydra/src/hic.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.4 by nmav, Sat Sep 28 08:50:07 2002 UTC revision 1.5 by nmav, Sat Sep 28 10:05:00 2002 UTC
# Line 19  Line 19 
19   */   */
20    
21  #include "boa.h"  #include "boa.h"
22    #include <signal.h>             /* signal */
23    
24  /* Hydra Internally handled CGIs (HIC HIC)  /* Hydra Internally handled CGIs (HIC HIC)
25   *   *
# Line 28  Line 29 
29   * uses one pipe to communicate with the others via hic_send_command().   * uses one pipe to communicate with the others via hic_send_command().
30   *   *
31   * If a request for a HIC file arrives, the server goes as a normal CGI   * If a request for a HIC file arrives, the server goes as a normal CGI
32   * creates a pipe, but does not fork. It sends instead a message to this   * creates a pipe, but does not fork. It enqueues a hic_request
33   * (HIC) thread to handle the request which includes the output fd.   * for this (HIC) thread, and sends a SIGUSR2 signal. The HIC thread is then
34     * waken up, and handles all pending requests.
35   *   *
36   * The HIC thread, when receives the message, parses the CGI in   * The HIC thread, when receives the message, parses the CGIs,
37   * FIFO mode (one CGI at the time), and sends the output to fd.   * one CGI at the time, and sends the output to fd.
38   *   *
39   * The benefit is that in no case the server is blocked. We may have   * The benefit is that in no case the server is blocked. We may have
40   * a problem, if the server only uses parsed CGIs.   * a performance problem, if the server only uses parsed CGIs.
41     *
42   */   */
43    
44  #ifdef ENABLE_HIC  #ifdef ENABLE_HIC
45    
46  #include "hic.h"  #include "hic.h"
47    
48  static ssize_t full_read(int fd, void *buf, size_t count);  #ifdef ENABLE_SMP
49  static ssize_t full_write(int fd, const void *buf, size_t count);  pthread_mutex_t hic_lock = PTHREAD_MUTEX_INITIALIZER;
50  static int process_command(hic_stuff * cmd);  #endif
51    
52  void* hic_main_loop( void* cml)  typedef struct _hic_request {
53  {     struct _hic_request *next;
54     int max_fd, ret;     struct _hic_request *prev;
55     struct timeval req_timeout;     hic_stuff command;
56     fd_set read_fdset;  } hic_request;
57     hic_stuff cmd;  
58     int *command_line = cml; /* this is an int[2] */  hic_request * hic_request_head = NULL;
59    
60    static int process_hic_request(hic_request * cmd);
61    void hic_dequeue(hic_request ** head, hic_request * req);
62    void hic_enqueue(hic_request ** head, hic_request * req);
63    int hic_sigchld_flag = 0; /* if we received a SIGCHLD signal, then this flag
64                            * is non zero */
65    
66     FD_ZERO(&read_fdset);  void *hic_main_loop(void *cml)
67    {
68       hic_request* current, *next;
69    
70     while (1) {     while (1) {
71          for (current = hic_request_head;current;current=next) {
72    
73        time(&current_time);  #ifdef ENABLE_SMP
74             pthread_mutex_lock(&hic_lock);
75        req_timeout.tv_sec = REQUEST_TIMEOUT;  #endif
76        req_timeout.tv_usec = 0l; /* reset timeout */           next = current->next;
77    #ifdef ENABLE_SMP
78        max_fd = -1;           pthread_mutex_unlock(&hic_lock);
79    #endif
       FD_SET(command_line[0], &read_fdset);  
       max_fd = command_line[0];  
   
       if (select(max_fd + 1, &read_fdset, NULL, NULL, &req_timeout) == -1) {  
          if (errno == EINTR)  
             continue;           /* while(1) */  
          else if (errno != EBADF) {  
             log_error_time();  
             fprintf(stderr, "hic: Error while processing command. %s.\n", strerror(errno));  
             exit(1);  
          }  
       }  
   
       if (FD_ISSET(command_line[0], &read_fdset)) {  
          /* read a command */  
          if ((ret =  
               full_read(command_line[0], &cmd,  
                         sizeof(cmd))) < sizeof(cmd)) {  
             log_error_time();  
             if (ret == 0) {     /* normal shutdown */  
                log_error_time();  
                fprintf(stderr, "Shutting down...");  
                close(command_line[0]);  
                return NULL;  
             }  
             fprintf(stderr, "hic: Error while receiving command. %s.\n",  
                     strerror(errno));  
             exit(1);  
          }  
80    
81           if (process_command(&cmd) == -1) {           if (process_hic_request( current) == -1) {
82              log_error_time();              log_error_time();
83              fprintf(stderr, "hic: Error while processing command.\n");              fprintf(stderr, "hic: Error while processing command.\n");
84              exit(1);              exit(1);
85           }           }
86        }        }
87          
88          /* If somebody sends a command, then he should
89           * send a sigusr2 as well.
90           */
91          if (!hic_request_head) pause();
92    
93          if (hic_sigchld_flag)
94             sigchld_run();
95          
96    
97     }     }
98    
99  }  }
100    
101  static int process_command(hic_stuff * cmd)  static int process_hic_request(hic_request * req)
102  {  {
103  hic_module_st * hst;     hic_module_st *hst;
104       hic_stuff* cmd = &req->command;
105      
106    #ifdef ENABLE_SMP
107       pthread_mutex_lock(&hic_lock);
108    #endif
109       hic_dequeue( &hic_request_head, req);
110    #ifdef ENABLE_SMP
111       pthread_mutex_unlock(&hic_lock);
112    #endif
113    
114     hst = find_hic_appr_module( get_mime_type(cmd->path_translated), 0);     hst = find_hic_appr_module(get_mime_type(cmd->path_translated), 0);
115     if (hst == NULL) {     if (hst == NULL) {
116        log_error_time();        log_error_time();
117        fprintf(stderr, "Could not find HIC handler for '%s'\n", cmd->path_translated);        fprintf(stderr, "Could not find HIC handler for '%s'\n",
118        close( cmd->out_fd);                cmd->path_translated);
119          close(cmd->out_fd);
120          free( req);
121        return 0;        return 0;
122     }     }
123    
124     hst->request( cmd);     hst->request(cmd);
125     close( cmd->out_fd);     close(cmd->out_fd);
126       free( req);
127    
128  /*  /*
129     log_error_time();     log_error_time();
# Line 129  hic_module_st * hst; Line 133  hic_module_st * hst;
133     return 0;     return 0;
134  }  }
135    
 static ssize_t full_read(int fd, void *buf, size_t count)  
 {  
    size_t nleft;  
    ssize_t nread;  
    char *ptr;  
   
    ptr = buf;  
    nleft = count;  
    while (nleft > 0) {  
       if ((nread = read(fd, ptr, nleft)) == -1) {  
          if (errno == EINTR) {  
             nread = 0;  
          } else  
             return -1;  
       } else if (nread == 0)  
          break;  
   
       nleft -= nread;  
       ptr += nread;  
    }  
   
    return count - nleft;  
   
 }  
   
 static ssize_t full_write(int fd, const void *buf, size_t count)  
 {  
    size_t nleft;  
    ssize_t nwritten;  
    const char *ptr;  
   
    ptr = buf;  
    nleft = count;  
    while (nleft > 0) {  
       if ((nwritten = write(fd, ptr, nleft)) == -1) {  
          if (errno == EINTR) {  
             nwritten = 0;  
          } else  
             return -1;  
       }  
   
       nleft -= nwritten;  
       ptr += nwritten;  
    }  
   
    return count;  
   
 }  
   
 #ifdef ENABLE_SMP  
 pthread_mutex_t hic_lock = PTHREAD_MUTEX_INITIALIZER;  
 #endif  
   
 extern int hic_write_fd;  
   
136  /* Sends a command to a HIC thread.  /* Sends a command to a HIC thread.
137   */   */
138  int hic_send_command( request *req, int out_fd)  int hic_send_command(request * req, int out_fd)
139  {  {
140  hic_stuff x;     hic_request *x;
 int ret;  
141    
142  x.cgi_env = req->cgi_env;     x = malloc( sizeof( hic_request));
143  x.cgi_env_max = req->cgi_env_index;     if (x==NULL)
144  x.one_one = 0;        return -1;
145  x.post_data_fd = req->post_data_fd;  
146  x.out_fd = out_fd;     x->next = x->prev = NULL;
147  x.request_uri = req->request_uri;     x->command.cgi_env = req->cgi_env;
148  x.path_translated = req->path_translated;     x->command.cgi_env_max = req->cgi_env_index;
149       x->command.one_one = 0;
150       x->command.post_data_fd = req->post_data_fd;
151       x->command.out_fd = out_fd;
152       x->command.request_uri = req->request_uri;
153       x->command.path_translated = req->path_translated;
154    
155  #ifdef ENABLE_SMP  #ifdef ENABLE_SMP
156  pthread_mutex_lock( &hic_lock);     pthread_mutex_lock(&hic_lock);
157  #endif  #endif
158      
159  ret = full_write( hic_write_fd, &x, sizeof(x));     hic_enqueue( &hic_request_head, x);
   
160  #ifdef ENABLE_SMP  #ifdef ENABLE_SMP
161  pthread_mutex_unlock( &hic_lock);     /* Notify the main loop */
162       pthread_kill( hic_tid, SIGUSR2);
163  #endif  #endif
164    
165  if (ret==sizeof(x)) return 1;  #ifdef ENABLE_SMP
166       pthread_mutex_unlock(&hic_lock);
167  log_error_time();  #endif
 fprintf(stderr, "Error sending to HIC thread.\n");  
 /* this should be a fatal error */  
   
 return -1;  
   
 }  
   
   
 #endif /* ENABLE_HIC */  
   
168    
169  #ifdef TEST     return 1;
170    
 int main()  
 {  
 int fd[2];  
 hic_stuff x;  
 pthread_t tid;  
   
 _php_hic_init();  
   
 memset( &x, 0, sizeof(x));  
   
   
 x.remote_address="127.0.0.1";  
 x.server_port = 8080;  
 x.out_fd  = STDOUT_FILENO;  
 x.script_name = "/test.php";  
 x.content_type = "text/html; charset=ISO-8859-7";  
 x.query_string = "STRING";  
 x.path_translated = "/tmp/test.php";  
 x.request_uri = "/test.php";  
 x.path_info = "/tmp/test.php";  
 x.str_method = "GET";  
 x.server_name = "Hydra.localhost";  
 x.server_port = 80;  
 x.http_version = "HTTP/1.1";  
 x.post_data_fd = -1;  
   
 if (pipe( fd) < 0) {  
   fprintf(stderr, "ERROR IN PIPE\n");  
   exit(1);  
171  }  }
172    
173  pthread_create( &tid, NULL, &hic_main_loop, (void*)fd);  /* Implement a basic queue for HIC stuff. This is created after
174     * queue.c.
175  fprintf(stderr, "Spawned %u\n", tid);   */
 sleep(2);  
   
 fprintf(stderr, "Written command\n");  
 write( fd[1], &x, sizeof(x));  
   
 sleep(5);  
   
 close(fd[1]);  
   
 pause();  
176    
177  return 0;  #include "queue.h"
 }  
178    
179  #endif  ENQUEUE_FUNCTION( hic_enqueue, hic_request)
180    DEQUEUE_FUNCTION( hic_dequeue, hic_request)
181    
182    #endif  /* ENABLE_HIC */

Legend:
Removed from v.1.4  
changed lines
  Added in v.1.5

webmaster@linux.gr
ViewVC Help
Powered by ViewVC 1.1.26