httpd-modules-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Niko Goutte <ngou...@hotmail.com>
Subject RE: cpu 100%
Date Thu, 31 Mar 2011 15:08:04 GMT

> Date: Thu, 31 Mar 2011 15:01:48 +0200
> Subject: Re: cpu 100%
> From: sorinm@gmail.com
> To: modules-dev@httpd.apache.org
> 
> On Thu, Mar 31, 2011 at 14:32, Niko Goutte <ngoutte@hotmail.com> wrote:
> >
> > Hello,
> >
> > I developped an apache module which send small data coming from file.
> > A client request from file through a Get request and data are sent with block
> > size equals to 100KB.
> > One 100KB buffer is allocated in the pool, then each buffer are used to create
> > one bucket that will be sent just after being inserted into the brigade.
> > To sum up:
> > ----------------------------------------------------------------------------------------------------------------------------
> > apr_bucket_brigade *bb;
> > apr_bucket* b;
> >
> > bb = apr_brigade_create(r->pool, r->connection->bucket_alloc);
> > Buf = apr_palloc(r->pool,100KB);
> >
> > while(lastBufferToSend==false)
> > {
> >  Processing(Buf);
> >
> >  b = apr_bucket_pool_create(Buf ,size, r->pool, r->connection->bucket_alloc)
;
> >
> >  APR_BRIGADE_INSERT_TAIL(bb, b);
> >  APR_BRIGADE_INSERT_TAIL(bb,apr_bucket_flush_create(bb->bucket_alloc));
> >
> >  if(lastBufferToSend)
> >  {
> >    APR_BRIGADE_INSERT_TAIL(bb,apr_bucket_eos_create(bb->bucket_alloc));
> >  }
> >
> >  rv = ap_pass_brigade(r->output_filters, bb);
> >  if (rv != APR_SUCCESS)
> >  {
> >    return  HTTP_INTERNAL_SERVER_ERROR;
> >  }
> >
> >  apr_brigade_cleanup(bb);
> > }
> >
> > apr_brigade_destroy(bb);
> > ----------------------------------------------------------------------------------------------------------------------------
> >
> >
> > I want to call ap_pass_brigade for each buffer because I want the module to
> > send immediatly 100KB.
> >
> > Clients don't have to wait for the complete processing of the file more than
> > 2GB. They receive small blocks until the end.
> >
> > --------------------------------------------------------------------------------------------------------------------------
> >
> >
> > Apache Server is in prefork mode.
> > <IfModule prefork.c>
> > StartServers 8
> > MinSpareServers 5
> > MaxSpareServers 20
> > ServerLimit 256
> > MaxClients 256
> > MaxRequestsPerChild 4000
> > </IfModule>
> >
> > In worker mode, everything is excepted 10 bytes that are send in addition including
value
> > "\n256\r\n" : it is very strange because the sum of every chunk corrsesponds exactly
to the expected size.
> > <IfModule worker.c>
> > StartServers 2
> > MinSpareThreads 25
> > MaxSpareThreads 75
> > ThreadPerChild 64
> > MaxClients 1024
> > MaxRequestsPerChild 0
> > </IfModule>
> >
> > --------------------------------------------------------------------------------------------------------------------------
> >
> > MY PROBLEMS:
> >
> > In prefork mode, the first 8 client requests (which corresponds to the StartServers
= 8) are well processed. My client received all data, everything is fine.
> > But the 9th freezes the module in ap_pass_brigade function. httpd is freezed with
100% cpu on this process.
> >
> > In worker mode, it is ok excepted the 10 bytes added. It seems that it is linked
with apr_brigade_destroy or apr_bucket_delete(b).
> 
> 
> Are you sure that the value of lastBufferToSend changes in your while-loop?
> 
> Can you post your exact code to see how you add the 10 bytes?
> 
> Sorin
-------------------------------------------------------------------------------------------------------------------------------
HERE IS:
#include <httpd.h>
#include <http_config.h>
#include <http_protocol.h>
#include <http_request.h>
#include <http_log.h>
#include <ap_compat.h>
#include <apr_buckets.h>
#include <apr_strings.h>


#define ASE_FILE_SIZE                            512000
#define ASE_BUFFER_SIZE           104858

module AP_MODULE_DECLARE_DATA     ase_mod_module;
#define ASE_MOD_HANDLER "ase-mod.extensions"
 
static int ase_mod_handler(request_rec *r)
{
    apr_status_t rv = APR_SUCCESS;
    apr_bucket_brigade* bb = NULL;;
    apr_bucket* b = NULL;;
    char filename[256];
    
    /* First, some housekeeping. */
    if (((!r->handler) != 0)|| (strcmp(r->handler, ASE_MOD_HANDLER)))
    {
        /* r->handler wasn't "ase_mod", so it's none of our business */
        ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server,"Decline processing file %s is
not %s and handler %s", r->filename,ASE_MOD_HANDLER,r->handler);
        return DECLINED;
    }
    
    if (r->method_number != M_GET)
    {
        ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server,"Error METHOD_NOT_ALLOWED (%d)",r->method_number);
        return HTTP_METHOD_NOT_ALLOWED;
    }

    ap_log_error(APLOG_MARK, APLOG_INFO, 0, r->server,"%s",r->the_request);
            
    // Construct filename
    strncpy(filename, r->filename, sizeof(filename) / sizeof(char) - 1);
    filename[sizeof(filename) / sizeof(char) - 1] = '\0';
        
    ap_log_error(APLOG_MARK, APLOG_INFO, 0, r->server,"filename = %s",filename);
    
    int DataSize = ASE_FILE_SIZE;

    ap_set_content_type(r, "video/ase");
    
    ap_update_mtime(r, r->finfo.mtime);
    ap_set_last_modified(r);
    
    apr_table_setn(r->headers_out, "Accept-Ranges", "bytes");
 
    r->vlist_validator = apr_pstrcat(r->pool, "X",apr_itoa(r->pool, DataSize), "\"",
NULL);
    ap_set_etag(r);
    
    char content_range[64];            
    sprintf(content_range,"bytes %d-%d/%d",0,ASE_FILE_SIZE-1,ASE_FILE_SIZE);
    ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server,"Add content range %s",content_range);
    apr_table_setn(r->headers_out, "Content-Range",content_range);
    
    r->status = HTTP_OK;

    bb = apr_brigade_create(r->pool, r->connection->bucket_alloc);
    char* Buf;
    Buf = apr_palloc(r->pool,ASE_BUFFER_SIZE);
    int size = ASE_BUFFER_SIZE;
                            
    unsigned int count = 0;
    while(DataSize>0)
    {
        if((DataSize - size)<0)
        {
            size = DataSize;
        }
        
        memset(Buf,count,size);
            
        b = apr_bucket_pool_create(Buf ,size, r->pool, r->connection->bucket_alloc)
;
        
        APR_BRIGADE_INSERT_TAIL(bb, b);
        APR_BRIGADE_INSERT_TAIL(bb,apr_bucket_flush_create(bb->bucket_alloc));
        
        if(DataSize <= size)
        {    
            APR_BRIGADE_INSERT_TAIL(bb,apr_bucket_eos_create(bb->bucket_alloc));
            ap_log_error(APLOG_MARK, APLOG_INFO, 0, r->server,"APR_BRIGADE_INSERT_TAIL
EOS Bucket");
        }
        
        rv = ap_pass_brigade(r->output_filters, bb);
        
        if (rv != APR_SUCCESS)
        {
            ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server,"HTTP_INTERNAL_SERVER_ERROR
ap_pass_brigade ");
            r->status = HTTP_INTERNAL_SERVER_ERROR;
            return r->status;
        }
            
        DataSize = DataSize - size;
        count++;
        ap_log_error(APLOG_MARK, APLOG_INFO, 0, r->server,"ap_pass_brigade, DataSize =
 %d and Size = %d",DataSize, size );
        
        apr_brigade_cleanup(bb);
    }
        
    ap_log_error(APLOG_MARK, APLOG_INFO, 0, r->server,"Out of While");
    
    apr_bucket_delete(b);
    //apr_brigade_destroy(bb);
    ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server,"End return %d",r->status);
    
    return r->status;
}

static void ase_mod_hooks(apr_pool_t *pool)
{
    if(pool){}
    
    ap_hook_handler(ase_mod_handler, NULL, NULL, APR_HOOK_MIDDLE);
}

module AP_MODULE_DECLARE_DATA ase_mod_module = {
  STANDARD20_MODULE_STUFF,
    NULL,                            /*create dir config     */
    NULL,                            /*merge dir config         */
    NULL,                                              /*create server config*/ 
    NULL,                                           /*merge server config */
    NULL,                                      /*command table             */
    ase_mod_hooks
};
-------------------------------------------------------------------------------------------------------------------------------
I would like to understand first why this module crashes with a segmentation fault in prefork
mode on the 9th simple request:
curl http://IP/filename.ext

where .ext is the "ase-mod.extensions"

Thank you.


 		 	   		  
Mime
  • Unnamed multipart/alternative (inline, None, 0 bytes)
View raw message