View | Details | Raw Unified | Return to bug 39380
Collapse All | Expand All

(-)mod_disk_cache.c.ls-rwc-fixups (-2 / +295 lines)
Lines 22-27 Link Here
22
#include "util_filter.h"
22
#include "util_filter.h"
23
#include "util_script.h"
23
#include "util_script.h"
24
#include "util_charset.h"
24
#include "util_charset.h"
25
#include "ap_mpm.h"
26
25
27
26
/*
28
/*
27
 * mod_disk_cache: Disk Based HTTP 1.1 Cache.
29
 * mod_disk_cache: Disk Based HTTP 1.1 Cache.
Lines 1677-1682 static apr_status_t copy_body(apr_pool_t Link Here
1677
}
1679
}
1678
1680
1679
1681
1682
/* Provide srcfile and srcinfo containing
1683
   APR_FINFO_INODE|APR_FINFO_MTIME to make sure we have opened the right file
1684
   (someone might have just replaced it which messes up things).
1685
*/
1686
static apr_status_t copy_body_nofd(apr_pool_t *p, const char *srcfile, 
1687
                                   apr_off_t srcoff, apr_finfo_t *srcinfo,
1688
                                   const char *destfile, apr_off_t destoff, 
1689
                                   apr_off_t len)
1690
{
1691
    apr_status_t rc;
1692
    apr_file_t *srcfd, *destfd;
1693
    apr_finfo_t finfo;
1694
1695
    rc = apr_file_open(&srcfd, srcfile, APR_READ | APR_BINARY, 0, p);
1696
    if(rc != APR_SUCCESS) {
1697
        return rc;
1698
    }
1699
    rc = apr_file_info_get(&finfo, APR_FINFO_INODE|APR_FINFO_MTIME, srcfd);
1700
    if(rc != APR_SUCCESS) {
1701
        return rc;
1702
    }
1703
    if(srcinfo->inode != finfo.inode || srcinfo->mtime < finfo.mtime) {
1704
        return APR_EGENERAL;
1705
    }
1706
1707
    rc = apr_file_open(&destfd, destfile, APR_WRITE | APR_BINARY, 0, p);
1708
    if(rc != APR_SUCCESS) {
1709
        return rc;
1710
    }
1711
1712
    rc = copy_body(p, srcfd, srcoff, destfd, destoff, len);
1713
    apr_file_close(srcfd);
1714
    if(rc != APR_SUCCESS) {
1715
        apr_file_close(destfd);
1716
        return rc;
1717
    }
1718
1719
    return apr_file_close(destfd);
1720
}
1721
1722
1723
#if APR_HAS_THREADS
1724
static apr_status_t bgcopy_thread_cleanup(void *data)
1725
{
1726
    copyinfo *ci = data;
1727
    apr_status_t rc, ret;
1728
    apr_pool_t *p;
1729
1730
    /* FIXME: Debug */
1731
    ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ci->s,
1732
                 "disk_cache: bgcopy_thread_cleanup: %s -> %s",
1733
                 ci->srcfile, ci->destfile);
1734
1735
    rc = apr_thread_join(&ret, ci->t);
1736
    if(rc != APR_SUCCESS) {
1737
        ap_log_error(APLOG_MARK, APLOG_ERR, rc, ci->s,
1738
                     "disk_cache: bgcopy_thread_cleanup: apr_thread_join "
1739
                     "failed %s -> %s", ci->srcfile, ci->destfile);
1740
        return rc;
1741
    }
1742
    if(ret != APR_SUCCESS) {
1743
        ap_log_error(APLOG_MARK, APLOG_ERR, ret, ci->s,
1744
                     "disk_cache: Background caching body %s -> %s failed",
1745
                     ci->srcfile, ci->destfile);
1746
    }
1747
1748
    /* FIXME: Debug */
1749
    ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ci->s,
1750
                 "disk_cache: bgcopy_thread_cleanup: SUCCESS %s -> %s",
1751
                 ci->srcfile, ci->destfile);
1752
1753
    /* Destroy our private pool */
1754
    p = ci->pool;
1755
    apr_pool_destroy(p);
1756
1757
    return APR_SUCCESS;
1758
}
1759
1760
1761
static void *bgcopy_thread(apr_thread_t *t, void *data)
1762
{
1763
    copyinfo *ci = data;
1764
    apr_pool_t *p;
1765
    apr_status_t rc;
1766
1767
    p = apr_thread_pool_get(t);
1768
1769
    /* FIXME: Debug */
1770
    ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ci->s,
1771
                 "disk_cache: bgcopy_thread: start %s -> %s",
1772
                 ci->srcfile, ci->destfile);
1773
1774
    rc = copy_body_nofd(p, ci->srcfile, ci->srcoff, &(ci->srcinfo), 
1775
                        ci->destfile, ci->destoff, ci->len);
1776
1777
    if(rc != APR_SUCCESS) {
1778
        apr_file_remove(ci->destfile, p);
1779
    }
1780
1781
    /* FIXME: Debug */
1782
    ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ci->s,
1783
                 "disk_cache: bgcopy_thread: done %s -> %s",
1784
                 ci->srcfile, ci->destfile);
1785
1786
    apr_thread_exit(t, rc);
1787
    return NULL;
1788
}
1789
#endif /* APR_HAS_THREADS */
1790
1791
1792
#if APR_HAS_FORK
1793
static apr_status_t bgcopy_child_cleanup(void *data) {
1794
    copyinfo *ci = data;
1795
    int status;
1796
    apr_exit_why_e why;
1797
    apr_pool_t *p;
1798
1799
    apr_proc_wait(ci->proc, &status, &why, APR_WAIT);
1800
    if(why == APR_PROC_EXIT) {
1801
        if(status != APR_SUCCESS) {
1802
            ap_log_error(APLOG_MARK, APLOG_ERR, status, ci->s,
1803
                         "disk_cache: Background caching body %s -> %s failed",
1804
                         ci->srcfile, ci->destfile);
1805
            return APR_SUCCESS;
1806
        }
1807
    }
1808
    else if(status & (APR_PROC_SIGNAL | APR_PROC_SIGNAL_CORE) ) {
1809
        ap_log_error(APLOG_MARK, APLOG_ERR, 0, ci->s,
1810
                     "disk_cache: Background caching body %s -> %s failed, "
1811
                     "caught signal %d", ci->srcfile, ci->destfile, status);
1812
        return APR_SUCCESS;
1813
    }
1814
1815
    /* Destroy our private pool */
1816
    p = ci->pool;
1817
    apr_pool_destroy(p);
1818
1819
    return APR_SUCCESS;
1820
}
1821
#endif /* APR_HAS_FORK */
1822
1823
1824
static apr_status_t do_bgcopy(apr_file_t *srcfd, apr_off_t srcoff, 
1825
                              apr_file_t *destfd, apr_off_t destoff, 
1826
                              apr_off_t len, conn_rec *c)
1827
{
1828
    copyinfo *ci;
1829
    apr_status_t rv;
1830
    apr_pool_t *newpool;
1831
    const char *srcfile, *destfile;
1832
    int mpm_query_info;
1833
1834
    /* It seems pool gets destroyed (ie. fd's closed) before our cleanup 
1835
       function is called when an error occurs (a dropped connection, for
1836
       example), so we need a pool of our own.
1837
     */
1838
    rv = apr_pool_create(&newpool, NULL);
1839
    if (rv != APR_SUCCESS) {
1840
        return rv;
1841
    }
1842
1843
    ci = apr_palloc(newpool, sizeof(*ci));
1844
    if(ci == NULL) {
1845
        apr_pool_destroy(newpool);
1846
        return APR_ENOMEM;
1847
    }
1848
1849
    rv = apr_file_name_get(&srcfile, srcfd);
1850
    if(rv != APR_SUCCESS) {
1851
        return rv;
1852
    }
1853
    rv = apr_file_info_get(&(ci->srcinfo), APR_FINFO_INODE|APR_FINFO_MTIME,
1854
                           srcfd);
1855
    if(rv != APR_SUCCESS) {
1856
        return rv;
1857
    }
1858
1859
    rv = apr_file_name_get(&destfile, destfd);
1860
    if(rv != APR_SUCCESS) {
1861
        return rv;
1862
    }
1863
1864
    ci->pool = newpool;
1865
    ci->srcfile = apr_pstrdup(newpool, srcfile);
1866
    ci->srcoff = srcoff;
1867
    ci->destfile = apr_pstrdup(newpool, destfile);
1868
    ci->destoff = destoff;
1869
    ci->len = len;
1870
    ci->s = c->base_server;
1871
1872
#if APR_HAS_THREADS
1873
    if(ap_mpm_query(AP_MPMQ_IS_THREADED, &mpm_query_info) == APR_SUCCESS) {
1874
        apr_threadattr_t *ta;
1875
        apr_thread_t *t;
1876
        rv = apr_threadattr_create(&ta, newpool);
1877
        if(rv != APR_SUCCESS) {
1878
            apr_pool_destroy(newpool);
1879
            return rv;
1880
        }
1881
1882
        apr_threadattr_detach_set(ta, FALSE);
1883
1884
        /* FIXME: This makes module unloadable on AIX */
1885
#if 0
1886
#ifdef AP_MPM_WANT_SET_STACKSIZE
1887
        if (ap_thread_stacksize != 0) {
1888
            apr_threadattr_stacksize_set(ta, ap_thread_stacksize);
1889
            ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, c->base_server,
1890
                    "disk_cache: BG thread stacksize set to %"
1891
                    APR_SIZE_T_FMT, ap_thread_stacksize);
1892
        }
1893
#endif /* AP_MPM_WANT_SET_STACKSIZE */
1894
#endif /* 0 */
1895
1896
        rv = apr_thread_create (&t, ta, bgcopy_thread, ci, newpool);
1897
        if (rv != APR_SUCCESS) {
1898
            apr_pool_destroy(newpool);
1899
            return rv;
1900
        }
1901
        ci->t = t;
1902
1903
        apr_pool_cleanup_register(c->pool, ci, 
1904
                                  bgcopy_thread_cleanup, apr_pool_cleanup_null);
1905
    }
1906
    else
1907
#endif /* APR_HAS_THREADS */
1908
#if APR_HAS_FORK
1909
    if(ap_mpm_query(AP_MPMQ_IS_FORKED, &mpm_query_info) == APR_SUCCESS) {
1910
        ci->proc = apr_palloc(newpool, sizeof(apr_proc_t));
1911
        if(ci->proc == NULL) {
1912
            apr_pool_destroy(newpool);
1913
            return APR_ENOMEM;
1914
        }
1915
        rv = apr_proc_fork(ci->proc, newpool);
1916
        if(rv == APR_INCHILD) {
1917
            /* Child */
1918
            rv = copy_body_nofd(ci->pool, ci->srcfile, ci->srcoff, 
1919
                                &(ci->srcinfo), ci->destfile, ci->destoff, 
1920
                                ci->len);
1921
            if(rv != APR_SUCCESS) {
1922
                apr_file_remove(ci->destfile, ci->pool);
1923
            }
1924
            exit(rv);
1925
        }
1926
        else if(rv == APR_INPARENT) {
1927
            apr_pool_cleanup_register(c->pool, ci, 
1928
                                      bgcopy_child_cleanup, 
1929
                                      apr_pool_cleanup_null);
1930
        }
1931
        else {
1932
            return rv;
1933
        }
1934
    }
1935
    else 
1936
#endif /* APR_HAS_FORK */
1937
    if(1)
1938
    {
1939
        rv = copy_body(newpool, srcfd, ci->srcoff, destfd, ci->destoff,
1940
                       ci->len);
1941
        apr_pool_destroy(newpool);
1942
    }
1943
1944
    return rv;
1945
}
1946
1947
1680
static apr_status_t replace_brigade_with_cache(cache_handle_t *h,
1948
static apr_status_t replace_brigade_with_cache(cache_handle_t *h,
1681
                                               request_rec *r,
1949
                                               request_rec *r,
1682
                                               apr_bucket_brigade *bb)
1950
                                               apr_bucket_brigade *bb)
Lines 1828-1835 static apr_status_t store_body(cache_han Link Here
1828
        e = APR_BRIGADE_FIRST(bb);
2096
        e = APR_BRIGADE_FIRST(bb);
1829
        a = e->data;
2097
        a = e->data;
1830
2098
1831
        rv = copy_body(r->pool, a->fd, e->start, dobj->fd, 0, 
2099
        if(dobj->file_size > conf->minbgsize) {
1832
                       dobj->file_size);
2100
            rv = do_bgcopy(a->fd, e->start, dobj->fd, 0, dobj->file_size,
2101
                           r->connection);
2102
        }
2103
        else {
2104
            rv = copy_body(r->pool, a->fd, e->start, dobj->fd, 0, 
2105
                           dobj->file_size);
2106
        }
1833
        if(rv != APR_SUCCESS) {
2107
        if(rv != APR_SUCCESS) {
1834
            ap_log_error(APLOG_MARK, APLOG_ERR, rv, r->server,
2108
            ap_log_error(APLOG_MARK, APLOG_ERR, rv, r->server,
1835
                         "disk_cache: Copying body failed, "
2109
                         "disk_cache: Copying body failed, "
Lines 1963-1968 static void *create_config(apr_pool_t *p Link Here
1963
    conf->maxfs = DEFAULT_MAX_FILE_SIZE;
2237
    conf->maxfs = DEFAULT_MAX_FILE_SIZE;
1964
    conf->minfs = DEFAULT_MIN_FILE_SIZE;
2238
    conf->minfs = DEFAULT_MIN_FILE_SIZE;
1965
    conf->updtimeout = DEFAULT_UPDATE_TIMEOUT;
2239
    conf->updtimeout = DEFAULT_UPDATE_TIMEOUT;
2240
    conf->minbgsize = DEFAULT_MIN_BACKGROUND_SIZE;
1966
2241
1967
    conf->cache_root = NULL;
2242
    conf->cache_root = NULL;
1968
    conf->cache_root_len = 0;
2243
    conf->cache_root_len = 0;
Lines 2065-2070 static const char Link Here
2065
}
2340
}
2066
2341
2067
2342
2343
static const char
2344
*set_cache_minbgsize(cmd_parms *parms, void *in_struct_ptr, const char *arg)
2345
{
2346
    disk_cache_conf *conf = ap_get_module_config(parms->server->module_config,
2347
                                                 &disk_cache_module);
2348
2349
    if (apr_strtoff(&conf->minbgsize, arg, NULL, 0) != APR_SUCCESS ||
2350
            conf->minbgsize < 0)
2351
    {   
2352
        return "CacheMinBGSize argument must be a non-negative integer representing the min size in bytes for a file to be eligable for background caching";
2353
    }
2354
2355
    return NULL;
2356
}
2357
2358
2068
static const command_rec disk_cache_cmds[] =
2359
static const command_rec disk_cache_cmds[] =
2069
{
2360
{
2070
    AP_INIT_TAKE1("CacheRoot", set_cache_root, NULL, RSRC_CONF,
2361
    AP_INIT_TAKE1("CacheRoot", set_cache_root, NULL, RSRC_CONF,
Lines 2079-2084 static const command_rec disk_cache_cmds Link Here
2079
                  "The maximum file size to cache a document"),
2370
                  "The maximum file size to cache a document"),
2080
    AP_INIT_TAKE1("CacheUpdateTimeout", set_cache_updtimeout, NULL, RSRC_CONF,
2371
    AP_INIT_TAKE1("CacheUpdateTimeout", set_cache_updtimeout, NULL, RSRC_CONF,
2081
                  "Timeout in ms for cache updates"),
2372
                  "Timeout in ms for cache updates"),
2373
    AP_INIT_TAKE1("CacheMinBGSize", set_cache_minbgsize, NULL, RSRC_CONF,
2374
                  "The minimum file size for background caching"),
2082
    {NULL}
2375
    {NULL}
2083
};
2376
};
2084
2377
(-)mod_disk_cache.h.rwc (+29 lines)
Lines 99-104 typedef struct disk_cache_object { Link Here
99
#define DEFAULT_MIN_FILE_SIZE 1
99
#define DEFAULT_MIN_FILE_SIZE 1
100
#define DEFAULT_MAX_FILE_SIZE 1000000
100
#define DEFAULT_MAX_FILE_SIZE 1000000
101
#define DEFAULT_UPDATE_TIMEOUT apr_time_from_sec(10)
101
#define DEFAULT_UPDATE_TIMEOUT apr_time_from_sec(10)
102
/* Background caching disabled by default */
103
#define DEFAULT_MIN_BACKGROUND_SIZE DEFAULT_MAX_FILE_SIZE
102
104
103
typedef struct {
105
typedef struct {
104
    const char* cache_root;
106
    const char* cache_root;
Lines 108-113 typedef struct { Link Here
108
    apr_off_t minfs;             /* minimum file size for cached files */
110
    apr_off_t minfs;             /* minimum file size for cached files */
109
    apr_off_t maxfs;             /* maximum file size for cached files */
111
    apr_off_t maxfs;             /* maximum file size for cached files */
110
    apr_interval_time_t updtimeout;   /* Cache update timeout */
112
    apr_interval_time_t updtimeout;   /* Cache update timeout */
113
    apr_off_t minbgsize;         /* minimum file size to do bg caching */
111
} disk_cache_conf;
114
} disk_cache_conf;
112
115
113
#define CACHE_ENODATA (APR_OS_START_USERERR+1)
116
#define CACHE_ENODATA (APR_OS_START_USERERR+1)
Lines 128-132 struct diskcache_bucket_data { Link Here
128
131
129
};
132
};
130
133
134
/* Stuff needed by the background copy thread */
135
typedef struct copyinfo copyinfo;
136
struct copyinfo {
137
    apr_off_t len;
138
    /* Source info */
139
    const char *srcfile;
140
    apr_finfo_t srcinfo;
141
    apr_off_t srcoff;
142
    /* Destination info */
143
    const char *destfile;
144
    apr_off_t destoff; 
145
146
    /* Our private pool */
147
    apr_pool_t *pool;
148
149
#if APR_HAS_THREADS
150
    /* Background process info */
151
    apr_thread_t *t;
152
#endif /* APR_HAS_THREADS */
153
#if APR_HAS_FORK
154
    apr_proc_t *proc;
155
#endif /* APR_HAS_FORK */
156
157
    /* For logging */
158
    const server_rec *s;
159
};
131
160
132
#endif /*MOD_DISK_CACHE_H*/
161
#endif /*MOD_DISK_CACHE_H*/

Return to bug 39380