lua_vmprep.c revision 19a96e59a4250d39c542c58782b5aa06d10d03f1
78cd48acd325773619d78ac0d7263a99a8922faend * Licensed to the Apache Software Foundation (ASF) under one or more
ab2c1c1c83ec91415565da5a71fbc15d9685caa6fielding * contributor license agreements. See the NOTICE file distributed with
ce9621257ef9e54c1bbe5ad8a5f445a1f211c2dcnd * this work for additional information regarding copyright ownership.
ce9621257ef9e54c1bbe5ad8a5f445a1f211c2dcnd * The ASF licenses this file to You under the Apache License, Version 2.0
ce9621257ef9e54c1bbe5ad8a5f445a1f211c2dcnd * (the "License"); you may not use this file except in compliance with
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding * the License. You may obtain a copy of the License at
ce9621257ef9e54c1bbe5ad8a5f445a1f211c2dcnd * Unless required by applicable law or agreed to in writing, software
ce9621257ef9e54c1bbe5ad8a5f445a1f211c2dcnd * distributed under the License is distributed on an "AS IS" BASIS,
ce9621257ef9e54c1bbe5ad8a5f445a1f211c2dcnd * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
ce9621257ef9e54c1bbe5ad8a5f445a1f211c2dcnd * See the License for the specific language governing permissions and
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding * limitations under the License.
2555a6b5da21d61804f47084d8fcc98eb4acbc42wrowevoid ap_lua_init_mutex(apr_pool_t *pool, server_rec *s)
1723d9ccdd3b647f5b7bae44cab9ab3eca7a4874dougm apr_thread_mutex_create(&ap_lua_mutex, APR_THREAD_MUTEX_DEFAULT, pool);
6335eb31f0f0ed54628a04ed32946360b8b77684minfrin/* forward dec'l from this file */
0f081398cf0eef8cc7c66a535d450110a92dc8aefieldingstatic void pstack_dump(lua_State *L, apr_pool_t *r, int level,
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding const char *msg)
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding ap_log_perror(APLOG_MARK, level, 0, r, "Lua Stack Dump: [%s]", msg);
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding int t = lua_type(L, i);
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding switch (t) {
a812b025d139f465a31c76fc02ed162ed5271b03nd ap_log_perror(APLOG_MARK, level, 0, r, "%d: userdata", i);
a812b025d139f465a31c76fc02ed162ed5271b03nd ap_log_perror(APLOG_MARK, level, 0, r, "%d: lightuserdata",
33cb45dc8c5106018b7c2f6ae42478b109423e0eniq i) ? "true" :
1dac466bcc84f8ebf410016dcf2a4cd4312e8611wrowe ap_log_perror(APLOG_MARK, level, 0, r, "%d: <table>", i);
38fd849bd99e2765ee633b6dc576b5f17acdc455wrowe ap_log_perror(APLOG_MARK, level, 0, r, "%d: <thread>", i);
38fd849bd99e2765ee633b6dc576b5f17acdc455wrowe ap_log_perror(APLOG_MARK, level, 0, r, "%d: <function>", i);
01261c7d9578aadd1891f94c8ee03f32ba51db3dmturk/* BEGIN modules*/
38fd849bd99e2765ee633b6dc576b5f17acdc455wrowe/* BEGIN apache lmodule */
38fd849bd99e2765ee633b6dc576b5f17acdc455wrowe#define makeintegerfield(L, n) lua_pushinteger(L, n); lua_setfield(L, -2, #n)
38fd849bd99e2765ee633b6dc576b5f17acdc455wroweAP_LUA_DECLARE(void) ap_lua_load_apache2_lmodule(lua_State *L)
38fd849bd99e2765ee633b6dc576b5f17acdc455wrowe makeintegerfield(L, HTTP_CONTINUE);
38fd849bd99e2765ee633b6dc576b5f17acdc455wrowe makeintegerfield(L, HTTP_SWITCHING_PROTOCOLS);
1dac466bcc84f8ebf410016dcf2a4cd4312e8611wrowe makeintegerfield(L, HTTP_PROCESSING);
38fd849bd99e2765ee633b6dc576b5f17acdc455wrowe makeintegerfield(L, HTTP_OK);
38fd849bd99e2765ee633b6dc576b5f17acdc455wrowe makeintegerfield(L, HTTP_CREATED);
9621e4c4056383e4a2b844b14687bae500b33a82wrowe makeintegerfield(L, HTTP_ACCEPTED);
01261c7d9578aadd1891f94c8ee03f32ba51db3dmturk makeintegerfield(L, HTTP_NON_AUTHORITATIVE);
01261c7d9578aadd1891f94c8ee03f32ba51db3dmturk makeintegerfield(L, HTTP_NO_CONTENT);
01261c7d9578aadd1891f94c8ee03f32ba51db3dmturk makeintegerfield(L, HTTP_RESET_CONTENT);
01261c7d9578aadd1891f94c8ee03f32ba51db3dmturk makeintegerfield(L, HTTP_PARTIAL_CONTENT);
9621e4c4056383e4a2b844b14687bae500b33a82wrowe makeintegerfield(L, HTTP_MULTI_STATUS);
9621e4c4056383e4a2b844b14687bae500b33a82wrowe makeintegerfield(L, HTTP_ALREADY_REPORTED);
1dac466bcc84f8ebf410016dcf2a4cd4312e8611wrowe makeintegerfield(L, HTTP_IM_USED);
9621e4c4056383e4a2b844b14687bae500b33a82wrowe makeintegerfield(L, HTTP_MULTIPLE_CHOICES);
9621e4c4056383e4a2b844b14687bae500b33a82wrowe makeintegerfield(L, HTTP_MOVED_PERMANENTLY);
1dac466bcc84f8ebf410016dcf2a4cd4312e8611wrowe makeintegerfield(L, HTTP_MOVED_TEMPORARILY);
4c67ef499845a08771e81254ce6eb2324a160bc7wrowe makeintegerfield(L, HTTP_SEE_OTHER);
01261c7d9578aadd1891f94c8ee03f32ba51db3dmturk makeintegerfield(L, HTTP_NOT_MODIFIED);
01261c7d9578aadd1891f94c8ee03f32ba51db3dmturk makeintegerfield(L, HTTP_USE_PROXY);
01261c7d9578aadd1891f94c8ee03f32ba51db3dmturk makeintegerfield(L, HTTP_TEMPORARY_REDIRECT);
4c67ef499845a08771e81254ce6eb2324a160bc7wrowe makeintegerfield(L, HTTP_PERMANENT_REDIRECT);
4c67ef499845a08771e81254ce6eb2324a160bc7wrowe makeintegerfield(L, HTTP_BAD_REQUEST);
1dac466bcc84f8ebf410016dcf2a4cd4312e8611wrowe makeintegerfield(L, HTTP_UNAUTHORIZED);
4c67ef499845a08771e81254ce6eb2324a160bc7wrowe makeintegerfield(L, HTTP_PAYMENT_REQUIRED);
4c67ef499845a08771e81254ce6eb2324a160bc7wrowe makeintegerfield(L, HTTP_FORBIDDEN);
1dac466bcc84f8ebf410016dcf2a4cd4312e8611wrowe makeintegerfield(L, HTTP_NOT_FOUND);
1dac466bcc84f8ebf410016dcf2a4cd4312e8611wrowe makeintegerfield(L, HTTP_METHOD_NOT_ALLOWED);
1dac466bcc84f8ebf410016dcf2a4cd4312e8611wrowe makeintegerfield(L, HTTP_NOT_ACCEPTABLE);
1dac466bcc84f8ebf410016dcf2a4cd4312e8611wrowe makeintegerfield(L, HTTP_PROXY_AUTHENTICATION_REQUIRED);
1dac466bcc84f8ebf410016dcf2a4cd4312e8611wrowe makeintegerfield(L, HTTP_REQUEST_TIME_OUT);
1dac466bcc84f8ebf410016dcf2a4cd4312e8611wrowe makeintegerfield(L, HTTP_CONFLICT);
1dac466bcc84f8ebf410016dcf2a4cd4312e8611wrowe makeintegerfield(L, HTTP_GONE);
1dac466bcc84f8ebf410016dcf2a4cd4312e8611wrowe makeintegerfield(L, HTTP_LENGTH_REQUIRED);
1dac466bcc84f8ebf410016dcf2a4cd4312e8611wrowe makeintegerfield(L, HTTP_PRECONDITION_FAILED);
1dac466bcc84f8ebf410016dcf2a4cd4312e8611wrowe makeintegerfield(L, HTTP_REQUEST_ENTITY_TOO_LARGE);
1dac466bcc84f8ebf410016dcf2a4cd4312e8611wrowe makeintegerfield(L, HTTP_REQUEST_URI_TOO_LARGE);
1dac466bcc84f8ebf410016dcf2a4cd4312e8611wrowe makeintegerfield(L, HTTP_UNSUPPORTED_MEDIA_TYPE);
1dac466bcc84f8ebf410016dcf2a4cd4312e8611wrowe makeintegerfield(L, HTTP_RANGE_NOT_SATISFIABLE);
1dac466bcc84f8ebf410016dcf2a4cd4312e8611wrowe makeintegerfield(L, HTTP_EXPECTATION_FAILED);
41c38e78e8e5dc73544571cc2b749d40869e84fawrowe makeintegerfield(L, HTTP_UNPROCESSABLE_ENTITY);
41c38e78e8e5dc73544571cc2b749d40869e84fawrowe makeintegerfield(L, HTTP_LOCKED);
41c38e78e8e5dc73544571cc2b749d40869e84fawrowe makeintegerfield(L, HTTP_FAILED_DEPENDENCY);
41c38e78e8e5dc73544571cc2b749d40869e84fawrowe makeintegerfield(L, HTTP_UPGRADE_REQUIRED);
41c38e78e8e5dc73544571cc2b749d40869e84fawrowe makeintegerfield(L, HTTP_PRECONDITION_REQUIRED);
41c38e78e8e5dc73544571cc2b749d40869e84fawrowe makeintegerfield(L, HTTP_TOO_MANY_REQUESTS);
41c38e78e8e5dc73544571cc2b749d40869e84fawrowe makeintegerfield(L, HTTP_REQUEST_HEADER_FIELDS_TOO_LARGE);
41c38e78e8e5dc73544571cc2b749d40869e84fawrowe makeintegerfield(L, HTTP_INTERNAL_SERVER_ERROR);
41c38e78e8e5dc73544571cc2b749d40869e84fawrowe makeintegerfield(L, HTTP_NOT_IMPLEMENTED);
eee895b02dd7867622afd0a8a94f2efc7de9c618wrowe makeintegerfield(L, HTTP_BAD_GATEWAY);
01261c7d9578aadd1891f94c8ee03f32ba51db3dmturk makeintegerfield(L, HTTP_SERVICE_UNAVAILABLE);
01261c7d9578aadd1891f94c8ee03f32ba51db3dmturk makeintegerfield(L, HTTP_GATEWAY_TIME_OUT);
1d2ff7570139286b0f0d16f92187a16ed5932291mturk makeintegerfield(L, HTTP_VERSION_NOT_SUPPORTED);
1d2ff7570139286b0f0d16f92187a16ed5932291mturk makeintegerfield(L, HTTP_VARIANT_ALSO_VARIES);
eee895b02dd7867622afd0a8a94f2efc7de9c618wrowe makeintegerfield(L, HTTP_INSUFFICIENT_STORAGE);
eee895b02dd7867622afd0a8a94f2efc7de9c618wrowe makeintegerfield(L, HTTP_LOOP_DETECTED);
eee895b02dd7867622afd0a8a94f2efc7de9c618wrowe makeintegerfield(L, HTTP_NOT_EXTENDED);
01261c7d9578aadd1891f94c8ee03f32ba51db3dmturk makeintegerfield(L, HTTP_NETWORK_AUTHENTICATION_REQUIRED);
eee895b02dd7867622afd0a8a94f2efc7de9c618wrowe/* END apache2 lmodule */
4415d997ac73262e513c0a571bd5be4f609040bawrowe/* END library functions */
4415d997ac73262e513c0a571bd5be4f609040bawrowe/* callback for cleaning up a lua vm when pool is closed */
4415d997ac73262e513c0a571bd5be4f609040bawrowe ap_lua_server_spec* spec = (ap_lua_server_spec*) resource;
01261c7d9578aadd1891f94c8ee03f32ba51db3dmturk munge_path(L,
4415d997ac73262e513c0a571bd5be4f609040bawrowe lifecycle_pool,
4415d997ac73262e513c0a571bd5be4f609040bawrowe spec->package_paths,
4415d997ac73262e513c0a571bd5be4f609040bawrowe spec->file);
4415d997ac73262e513c0a571bd5be4f609040bawrowe * field -> "path" or "cpath"
4415d997ac73262e513c0a571bd5be4f609040bawrowe * sub_pat -> "?.lua"
4415d997ac73262e513c0a571bd5be4f609040bawrowe * rep_pat -> "./?.lua"
01261c7d9578aadd1891f94c8ee03f32ba51db3dmturk * pool -> lifecycle pool for allocations
01261c7d9578aadd1891f94c8ee03f32ba51db3dmturk * paths -> things to add
01261c7d9578aadd1891f94c8ee03f32ba51db3dmturk * file -> ???
4415d997ac73262e513c0a571bd5be4f609040bawrowe const char *field,
4415d997ac73262e513c0a571bd5be4f609040bawrowe const char *sub_pat,
eee895b02dd7867622afd0a8a94f2efc7de9c618wrowe const char *rep_pat,
00b70ae978854b5eb51722cbeda99c9067b5faf2mturk const char *file)
00b70ae978854b5eb51722cbeda99c9067b5faf2mturk const char *current;
00b70ae978854b5eb51722cbeda99c9067b5faf2mturk const char *parent_dir;
00b70ae978854b5eb51722cbeda99c9067b5faf2mturk const char *pattern;
00b70ae978854b5eb51722cbeda99c9067b5faf2mturk const char *modified;
38fd849bd99e2765ee633b6dc576b5f17acdc455wrowe pattern = apr_pstrcat(pool, parent_dir, sub_pat, NULL);
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard part = apr_pstrcat(pool, modified, ";", apr_array_pstrcat(pool, paths, ';'),
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddardstatic int loadjitmodule(lua_State *L, apr_pool_t *lifecycle_pool) {
33cb45dc8c5106018b7c2f6ae42478b109423e0eniq ap_log_perror(APLOG_MARK, APLOG_DEBUG, 0, lifecycle_pool, APLOGNO(01480)
33cb45dc8c5106018b7c2f6ae42478b109423e0eniqstatic apr_status_t vm_construct(lua_State **vm, void *params, apr_pool_t *lifecycle_pool)
50b2d068ddf98cf75622a0020cd143d379d1b235jfclere munge_path(L, "cpath", "?.so", "./?.so", lifecycle_pool,
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding luaL_loadbuffer(L, spec->bytecode, spec->bytecode_len, spec->file);
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding ap_log_perror(APLOG_MARK, APLOG_DEBUG, 0, lifecycle_pool, APLOGNO(01481)
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding if (rc != 0) {
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding ap_log_perror(APLOG_MARK, APLOG_ERR, 0, lifecycle_pool, APLOGNO(01482)
33cb45dc8c5106018b7c2f6ae42478b109423e0eniq lua_setfield(L, LUA_REGISTRYINDEX, "Apache2.Wombat.pool");
0f081398cf0eef8cc7c66a535d450110a92dc8aefieldingstatic ap_lua_vm_spec* copy_vm_spec(apr_pool_t* pool, ap_lua_vm_spec* spec)
16d38ac65d7e54cd44eeda7b23f84ee68b35094ewrowe ap_lua_vm_spec* copied_spec = apr_pcalloc(pool, sizeof(ap_lua_vm_spec));
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard copied_spec->bytecode = spec->bytecode ? apr_pstrdup(pool, spec->bytecode) : 0;
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard copied_spec->file = spec->file ? apr_pstrdup(pool, spec->file) : 0;
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard copied_spec->package_cpaths = apr_array_copy(pool, spec->package_cpaths);
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard copied_spec->package_paths = apr_array_copy(pool, spec->package_paths);
0f081398cf0eef8cc7c66a535d450110a92dc8aefieldingstatic apr_status_t server_vm_construct(lua_State **resource, void *params, apr_pool_t *pool)
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard ap_lua_server_spec* spec = apr_pcalloc(pool, sizeof(ap_lua_server_spec));
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard if (vm_construct(&L, params, pool) == APR_SUCCESS) {
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard spec->finfo = apr_pcalloc(pool, sizeof(ap_lua_finfo));
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard if (L != NULL) {
33cb45dc8c5106018b7c2f6ae42478b109423e0eniq lua_setfield(L, LUA_REGISTRYINDEX, "Apache2.Lua.server_spec");
33cb45dc8c5106018b7c2f6ae42478b109423e0eniq * Function used to create a lua_State instance bound into the web
33cb45dc8c5106018b7c2f6ae42478b109423e0eniq * server in the appropriate scope.
33cb45dc8c5106018b7c2f6ae42478b109423e0eniqAP_LUA_DECLARE(lua_State*)ap_lua_get_lua_state(apr_pool_t *lifecycle_pool,
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding hash = apr_psprintf(r->pool, "reslist:%s", spec->file);
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard if (apr_reslist_acquire(reslist, (void**) &sspec) == APR_SUCCESS) {
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding if (L == NULL) {
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding ap_lua_vm_spec* server_spec = copy_vm_spec(r->server->process->pool, spec);
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding apr_reslist_create(&reslist, spec->vm_min, spec->vm_max, spec->vm_max, 0,
11c3b5180e1de6776035320b012a28bb146e7b46chuck if (apr_reslist_acquire(reslist, (void**) &sspec) == APR_SUCCESS) {
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding if (L == NULL) {
9b3001f2097437c3c605d29e353fda5131b9952bminfrin ap_log_perror(APLOG_MARK, APLOG_DEBUG, 0, lifecycle_pool, APLOGNO(01483)
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe /* not available, so create */
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe apr_pool_userdata_set(L, spec->file, cleanup_lua, lifecycle_pool);
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard if (spec->codecache == AP_LUA_CACHE_FOREVER || (spec->bytecode && spec->bytecode_len > 0)) {
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe mkey = apr_psprintf(r->pool, "ap_lua_modified:%s", spec->file);
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe apr_pool_userdata_get((void **)&cache_info, mkey, lifecycle_pool);
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe cache_info = apr_pcalloc(lifecycle_pool, sizeof(ap_lua_finfo));
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe apr_pool_userdata_set((void*) cache_info, mkey, NULL, lifecycle_pool);
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe apr_stat(&lua_finfo, spec->file, APR_FINFO_MTIME|APR_FINFO_SIZE, lifecycle_pool);
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe /* On first visit, modified will be zero, but that's fine - The file is
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe loaded in the vm_construct function.
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe if ((cache_info->modified == lua_finfo.mtime && cache_info->size == lua_finfo.size) \
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe if (tryCache == 0 && spec->scope != AP_LUA_SCOPE_ONCE) {
8632261c895a84c88ae6ade6ea4c62b27bd22b3ebrianp ap_log_perror(APLOG_MARK, APLOG_DEBUG, 0, lifecycle_pool, APLOGNO(02332)
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe if (rc != 0) {