[mapserver-commits] r12169 - trunk/mapserver/mapcache/src

svn at osgeo.org svn at osgeo.org
Fri Aug 26 07:03:57 EDT 2011


Author: tbonfort
Date: 2011-08-26 04:03:57 -0700 (Fri, 26 Aug 2011)
New Revision: 12169

Added:
   trunk/mapserver/mapcache/src/lock.c
   trunk/mapserver/mapcache/src/source_gdal.c
Modified:
   trunk/mapserver/mapcache/src/cache_disk.c
   trunk/mapserver/mapcache/src/configuration.c
   trunk/mapserver/mapcache/src/fastcgi_geocache.c
   trunk/mapserver/mapcache/src/tileset.c
Log:
report errors back to users (will be configurable)
thomas.bonfort | 2010-12-09 16:13:51 +0100 (Thu, 09 Dec 2010)

Modified: trunk/mapserver/mapcache/src/cache_disk.c
===================================================================
--- trunk/mapserver/mapcache/src/cache_disk.c	2011-08-26 11:03:51 UTC (rev 12168)
+++ trunk/mapserver/mapcache/src/cache_disk.c	2011-08-26 11:03:57 UTC (rev 12169)
@@ -85,150 +85,8 @@
        return GEOCACHE_FALSE;
 }
 
-/**
- * \brief lock the given tile so other processes know it is being processed
- * 
- * this function creates a file with a .lck  extension and puts an exclusive lock on it
- * \sa geocache_cache::tile_lock()
- * \sa geocache_cache::tile_lock_exists()
- * \private \memberof geocache_cache_disk
- */
-void _geocache_cache_disk_tile_lock(geocache_context *ctx, geocache_tile *tile) {
-   char *filename;
-   char *basename;
-   char *dirname;
-   apr_file_t *f;
-   apr_status_t rv;
-   _geocache_cache_disk_tile_key_split(ctx, tile, &dirname, &basename);
-   GC_CHECK_ERROR(ctx);
-   rv = apr_dir_make_recursive(dirname,APR_OS_DEFAULT,ctx->pool);
-   if(rv != APR_SUCCESS) {
-      ctx->set_error(ctx, GEOCACHE_DISK_ERROR, "failed to create directory %s",dirname);
-      return;
-   }
-   filename = apr_psprintf(ctx->pool,"%s/%s.lck",dirname,basename);
-   /*create file, and fail if it already exists*/
-   if(apr_file_open(&f, filename,
-         APR_FOPEN_CREATE|APR_FOPEN_EXCL|APR_FOPEN_WRITE|APR_FOPEN_SHARELOCK|APR_FOPEN_BUFFERED|APR_FOPEN_BINARY,
-         APR_OS_DEFAULT, ctx->pool) != APR_SUCCESS) {
-      /* 
-       * opening failed, is this because we don't have write permissions, or because 
-       * the file already exists?
-       */
-      if(apr_file_open(&f, filename, APR_FOPEN_CREATE|APR_FOPEN_WRITE, APR_OS_DEFAULT, ctx->pool) != APR_SUCCESS) {
-         ctx->set_error(ctx, GEOCACHE_DISK_ERROR, "failed to create file %s",filename);
-         return; /* we could not create the file */
-      } else {
-         ctx->set_error(ctx, GEOCACHE_DISK_ERROR,  "failed to create lockfile %s, because it already exists",filename);
-         apr_file_close(f);
-         return; /* we have write access, but the file already exists */
-      }
-   }
-   rv = apr_file_lock(f, APR_FLOCK_EXCLUSIVE|APR_FLOCK_NONBLOCK);
-   if(rv != APR_SUCCESS) {
-      if(rv == EAGAIN) {
-         ctx->set_error(ctx, GEOCACHE_DISK_ERROR,   "####### TILE LOCK ######## file %s is already locked",filename);
-      } else {
-         ctx->set_error(ctx, GEOCACHE_DISK_ERROR,  "failed to lock file %s",filename);
-      }
-      return;
-   }
-   tile->lock = f;
-}
 
 /**
- * \brief unlock a previously locked tile
- * 
- * \private \memberof geocache_cache_disk
- * \sa geocache_cache::tile_unlock()
- * \sa geocache_cache::tile_lock_exists()
- */
-void _geocache_cache_disk_tile_unlock(geocache_context *ctx, geocache_tile *tile) {
-   apr_file_t *f = (apr_file_t*)tile->lock;
-   const char *fname;
-   if(!tile->lock) {
-      char *filename;
-      char *lockname;
-      _geocache_cache_disk_tile_key(ctx, tile, &filename);
-      GC_CHECK_ERROR(ctx);
-      ctx->log(ctx, GEOCACHE_ERROR,   "###### TILE UNLOCK ######### attempting to unlock tile %s not created by this thread", filename);
-      lockname = apr_psprintf(ctx->pool,"%s.lck",filename);
-      /*create file, and fail if it already exists*/
-      if(apr_file_open(&f, lockname,APR_FOPEN_READ,APR_OS_DEFAULT, ctx->pool) != APR_SUCCESS) {
-         ctx->set_error(ctx, GEOCACHE_DISK_ERROR,  "###### TILE UNLOCK ######### tile %s is not locked", lockname);
-         return;
-      }
-   } else {
-      f = (apr_file_t*)tile->lock;
-   }
-
-   apr_file_name_get(&fname,f);
-   apr_file_remove(fname,ctx->pool);
-
-   int rv = apr_file_unlock(f);
-   if(rv != APR_SUCCESS) {
-      ctx->set_error(ctx, GEOCACHE_DISK_ERROR, "failed to unlock file %s",fname);
-      return;
-   }
-   rv = apr_file_close(f);
-   if(rv != APR_SUCCESS) {
-      ctx->set_error(ctx, GEOCACHE_DISK_ERROR, "failed to close file %s", fname);
-      return;
-   }
-   tile->lock = NULL;
-}
-
-/**
- * \brief query tile to check if the corresponding lockfile exists
- * \private \memberof geocache_cache_disk
- * \sa geocache_cache::tile_lock()
- * \sa geocache_cache::tile_unlock()
- */
-int _geocache_cache_disk_tile_is_locked(geocache_context *ctx, geocache_tile *tile) {
-   char *filename;
-   char *lockname;
-   apr_file_t *f;
-   if(tile->lock)
-      return GEOCACHE_TRUE;
-   _geocache_cache_disk_tile_key(ctx, tile, &filename);
-   lockname = apr_psprintf(ctx->pool,"%s.lck",filename);
-   if(apr_file_open(&f, lockname,APR_FOPEN_READ,APR_OS_DEFAULT, ctx->pool) != APR_SUCCESS) {
-      return GEOCACHE_FALSE;
-   } else {
-      apr_file_close(f);
-      return GEOCACHE_TRUE;
-   }
-}
-
-/**
- * \brief wait for a lock on given tile
- * 
- * this function will not return until the lock on the tile has been removed
- * \private \memberof geocache_cache_disk
- * \sa geocache_cache::tile_lock_wait()
- */
-void _geocache_cache_disk_tile_wait_for_lock(geocache_context *ctx, geocache_tile *tile) {
-   char *filename;
-   char *lockname;
-   apr_file_t *f;
-#ifdef DEBUG
-   if(tile->lock) {
-      ctx->set_error(ctx,GEOCACHE_DISK_ERROR,  "### BUG ### waiting for a lock we have created ourself");
-      return;
-   }
-#endif
-   _geocache_cache_disk_tile_key(ctx, tile, &filename);
-   GC_CHECK_ERROR(ctx);
-   lockname = apr_psprintf(ctx->pool,"%s.lck",filename);
-   if(apr_file_open(&f, lockname,APR_FOPEN_READ,APR_OS_DEFAULT, ctx->pool) != APR_SUCCESS) {
-      ctx->set_error(ctx, GEOCACHE_DISK_ERROR,   "### BUG ### waiting for a lock on an unlocked file");
-      return;
-   }
-   apr_file_lock(f,APR_FLOCK_SHARED);
-   apr_file_close(f);
-}
-
-/**
  * \brief get file content of given tile
  * 
  * fills the geocache_tile::data of the given tile with content stored in the file
@@ -287,7 +145,7 @@
 void _geocache_cache_disk_set(geocache_context *ctx, geocache_tile *tile) {
    apr_size_t bytes;
    apr_file_t *f;
-   char *filename;
+   char *basename, *path, *filename;
 #ifdef DEBUG
    /* all this should be checked at a higher level */
    if(!tile->data || !tile->data->size) {
@@ -299,8 +157,15 @@
       return;
    }
 #endif
-   _geocache_cache_disk_tile_key(ctx, tile, &filename);
+   _geocache_cache_disk_tile_key_split(ctx, tile, &path, &basename);
    GC_CHECK_ERROR(ctx);
+   
+   if(APR_SUCCESS != apr_dir_make_recursive(path,APR_OS_DEFAULT,ctx->pool)) {
+       ctx->set_error(ctx, GEOCACHE_DISK_ERROR, "failed to create directory %s",path);
+       return;
+   }
+   
+   filename = apr_psprintf(ctx->pool,"%s/%s",path,basename);
 
    if(((geocache_cache_disk*)tile->tileset->cache)->symlink_blank) {
       geocache_image *image = geocache_imageio_decode(ctx, tile->data);
@@ -431,10 +296,6 @@
    cache->cache.tile_set = _geocache_cache_disk_set;
    cache->cache.configuration_check = _geocache_cache_disk_configuration_check;
    cache->cache.configuration_parse = _geocache_cache_disk_configuration_parse;
-   cache->cache.tile_lock = _geocache_cache_disk_tile_lock;
-   cache->cache.tile_unlock = _geocache_cache_disk_tile_unlock;
-   cache->cache.tile_lock_exists = _geocache_cache_disk_tile_is_locked;
-   cache->cache.tile_lock_wait = _geocache_cache_disk_tile_wait_for_lock;
    return (geocache_cache*)cache;
 }
 

Modified: trunk/mapserver/mapcache/src/configuration.c
===================================================================
--- trunk/mapserver/mapcache/src/configuration.c	2011-08-26 11:03:51 UTC (rev 12168)
+++ trunk/mapserver/mapcache/src/configuration.c	2011-08-26 11:03:57 UTC (rev 12169)
@@ -5,6 +5,7 @@
 #include <stdlib.h>
 #include <apr_strings.h>
 #include <apr_hash.h>
+#include <apr_file_io.h>
 
 geocache_cfg* geocache_configuration_create(apr_pool_t *pool) {
    geocache_cfg *cfg = (geocache_cfg*)apr_pcalloc(pool, sizeof(geocache_cfg));
@@ -23,6 +24,7 @@
          geocache_imageio_create_jpeg_format(pool,"JPEG",95),
          "JPEG");
    cfg->merge_format = geocache_configuration_get_image_format(cfg,"PNG");
+   cfg->lockdir = "/tmp/geocache_locks";
    return cfg;
 }
 
@@ -47,6 +49,7 @@
 }
 
 void geocache_configuration_add_tileset(geocache_cfg *config, geocache_tileset *tileset, const char * key) {
+   tileset->config = config;
    apr_hash_set(config->tilesets, key, APR_HASH_KEY_STRING, (void*)tileset);
 }
 
@@ -446,7 +449,8 @@
 
 void geocache_configuration_parse(geocache_context *ctx, const char *filename, geocache_cfg *config) {
    xmlDocPtr doc;
-
+   char *testlockfilename;
+   apr_file_t *testlockfile;
    doc = xmlReadFile(filename, NULL, 0);
    if (doc == NULL) {
       ctx->set_error(ctx,GEOCACHE_PARSE_ERROR, "libxml2 failed to parse file %s. Is it valid XML?", filename);
@@ -483,11 +487,13 @@
                   if(!value || !*value || xmlStrcmp(value, BAD_CAST "false")) {
                      config->services[GEOCACHE_SERVICE_WMS] = geocache_service_wms_create(ctx);
                   }
-               }else if(!xmlStrcmp(service_node->name, BAD_CAST "tms")) {
+                  xmlFree(value);
+               } else if(!xmlStrcmp(service_node->name, BAD_CAST "tms")) {
                   xmlChar* value = xmlNodeGetContent(service_node);
                   if(!value || !*value || xmlStrcmp(value, BAD_CAST "false")) {
                      config->services[GEOCACHE_SERVICE_TMS] = geocache_service_tms_create(ctx);
                   }
+                  xmlFree(value);
                }
             }
          } else if(!xmlStrcmp(cur_node->name, BAD_CAST "merge_format")) {
@@ -500,11 +506,16 @@
                
             }
             config->merge_format = format;
+         } else if(!xmlStrcmp(cur_node->name, BAD_CAST "lock_dir")) {
+            xmlChar *value = xmlNodeGetContent(cur_node);
+            config->lockdir = apr_pstrdup(ctx->pool, (char*)value);
+            xmlFree(value);
          } else {
             ctx->set_error(ctx, GEOCACHE_PARSE_ERROR, "failed to parse geocache config file %s: unknown tag <%s>",
                   filename, cur_node->name);
             return;
          }
+
       }
 
    } else {
@@ -515,6 +526,20 @@
       return;
    }
 
+   /* check our lock directory is valid and writable */
+   if(APR_SUCCESS != apr_dir_make_recursive(config->lockdir, APR_OS_DEFAULT, ctx->pool)) {
+       ctx->set_error(ctx, GEOCACHE_DISK_ERROR, "failed to create lock directory %s",config->lockdir);
+       return;
+   }
+   testlockfilename = apr_psprintf(ctx->pool,"%s/test.lock",config->lockdir);
+   if(apr_file_open(&testlockfile, testlockfilename, APR_FOPEN_CREATE|APR_FOPEN_WRITE,
+               APR_OS_DEFAULT, ctx->pool) != APR_SUCCESS) {
+       ctx->set_error(ctx, GEOCACHE_DISK_ERROR,  "failed to create test lockfile %s",testlockfilename);
+       return; /* we could not create the file */
+   }
+   apr_file_close(testlockfile);
+   apr_file_remove(testlockfilename,ctx->pool);
+
    if(!config->services[GEOCACHE_SERVICE_WMS] &&
          !config->services[GEOCACHE_SERVICE_TMS]) {
       ctx->set_error(ctx, GEOCACHE_PARSE_ERROR, "no services configured."

Modified: trunk/mapserver/mapcache/src/fastcgi_geocache.c
===================================================================
--- trunk/mapserver/mapcache/src/fastcgi_geocache.c	2011-08-26 11:03:51 UTC (rev 12168)
+++ trunk/mapserver/mapcache/src/fastcgi_geocache.c	2011-08-26 11:03:57 UTC (rev 12169)
@@ -105,11 +105,18 @@
    geocache_context_fcgi *ctx = apr_pcalloc(pool, sizeof(geocache_context_fcgi));
    ctx->ctx.pool = pool;
    init_fcgi_context(ctx);
-   ret = apr_proc_mutex_create(&ctx->mutex,"geocache_mutex",APR_LOCK_DEFAULT,pool);
+   ctx->ctx.log(ctx,GEOCACHE_DEBUG,"before mutex");
+   ret = apr_proc_mutex_child_init(&ctx->mutex,"geocache_mutex",pool);
+   ctx->ctx.log(ctx,GEOCACHE_DEBUG,"after mutex");
+
    if(ret != APR_SUCCESS) {
-      ctx->ctx.set_error(&ctx->ctx,GEOCACHE_MUTEX_ERROR,"failed to created mutex");
-   } else {
-      apr_pool_cleanup_register(pool,ctx->mutex,(void*)apr_proc_mutex_destroy, apr_pool_cleanup_null);
+       ctx->ctx.log(ctx,GEOCACHE_DEBUG,"create mutex");
+          ret = apr_proc_mutex_create(&ctx->mutex,"geocache_mutex",APR_LOCK_DEFAULT,pool);
+       if(ret != APR_SUCCESS) {
+          ctx->ctx.set_error(&ctx->ctx,GEOCACHE_MUTEX_ERROR,"failed to created mutex");
+       } else {
+          apr_pool_cleanup_register(pool,ctx->mutex,(void*)apr_proc_mutex_destroy, apr_pool_cleanup_null);
+       }
    }
    return ctx;
 }

Added: trunk/mapserver/mapcache/src/lock.c
===================================================================
--- trunk/mapserver/mapcache/src/lock.c	                        (rev 0)
+++ trunk/mapserver/mapcache/src/lock.c	2011-08-26 11:03:57 UTC (rev 12169)
@@ -0,0 +1,135 @@
+#include "geocache.h"
+#include <apr_file_io.h>
+#include <apr_strings.h>
+
+char *geocache_tileset_tile_lock_key(geocache_context *ctx, geocache_tile *tile) {
+  return apr_psprintf(ctx->pool,
+          "%s/%s-%d-%d-%d.lck",
+          tile->tileset->config->lockdir,
+          tile->tileset->name,
+          tile->z, tile->y, tile->x);
+}
+/**
+ * \brief lock the given tile so other processes know it is being processed
+ *
+ * this function creates a file with a .lck  extension and puts an exclusive lock on it
+ * \sa geocache_cache::tile_lock()
+ * \sa geocache_cache::tile_lock_exists()
+ * \private \memberof geocache_cache_disk
+ */
+void geocache_tileset_tile_lock(geocache_context *ctx, geocache_tile *tile) {
+  char *lockname;
+  apr_file_t *f;
+  apr_status_t rv;
+  lockname = geocache_tileset_tile_lock_key(ctx,tile);
+  /*create file, and fail if it already exists*/
+  if (apr_file_open(&f, lockname,
+          APR_FOPEN_CREATE | APR_FOPEN_EXCL | APR_FOPEN_WRITE | APR_FOPEN_SHARELOCK | APR_FOPEN_BUFFERED | APR_FOPEN_BINARY,
+          APR_OS_DEFAULT, ctx->pool) != APR_SUCCESS) {
+    /*
+     * opening failed, is this because we don't have write permissions, or because
+     * the file already exists?
+     */
+    if (apr_file_open(&f, lockname, APR_FOPEN_CREATE | APR_FOPEN_WRITE, APR_OS_DEFAULT, ctx->pool) != APR_SUCCESS) {
+      ctx->set_error(ctx, GEOCACHE_DISK_ERROR, "failed to create lockfile %s", lockname);
+      return; /* we could not create the file */
+    } else {
+      ctx->set_error(ctx, GEOCACHE_DISK_ERROR, "failed to create lockfile %s, because it already exists", lockname);
+      apr_file_close(f);
+      return; /* we have write access, but the file already exists */
+    }
+  }
+  rv = apr_file_lock(f, APR_FLOCK_EXCLUSIVE | APR_FLOCK_NONBLOCK);
+  if (rv != APR_SUCCESS) {
+    if (rv == EAGAIN) {
+      ctx->set_error(ctx, GEOCACHE_DISK_ERROR, "####### TILE LOCK ######## file %s is already locked", lockname);
+    } else {
+      ctx->set_error(ctx, GEOCACHE_DISK_ERROR, "failed to lock file %s", lockname);
+    }
+    return;
+  }
+  tile->lock = f;
+}
+
+/**
+ * \brief unlock a previously locked tile
+ *
+ * \sa geocache_cache::tile_unlock()
+ * \sa geocache_cache::tile_lock_exists()
+ */
+void geocache_tileset_tile_unlock(geocache_context *ctx, geocache_tile *tile) {
+  apr_file_t *f = (apr_file_t*) tile->lock;
+  const char *lockname;
+  if (!tile->lock) {
+    lockname = geocache_tileset_tile_lock_key(ctx, tile);
+    ctx->log(ctx, GEOCACHE_ERROR, "###### TILE UNLOCK ######### attempting to unlock tile %s not created by this thread", lockname);
+
+    /*fail if the lock does not exists*/
+    if (apr_file_open(&f, lockname, APR_FOPEN_READ, APR_OS_DEFAULT, ctx->pool) != APR_SUCCESS) {
+      ctx->set_error(ctx, GEOCACHE_DISK_ERROR, "###### TILE UNLOCK ######### tile %s is not locked", lockname);
+      return;
+    }
+  } else {
+    f = (apr_file_t*) tile->lock;
+    apr_file_name_get(&lockname, f);
+  }
+
+  
+  apr_file_remove(lockname, ctx->pool);
+
+  int rv = apr_file_unlock(f);
+  if (rv != APR_SUCCESS) {
+    ctx->set_error(ctx, GEOCACHE_DISK_ERROR, "failed to unlock file %s", lockname);
+    return;
+  }
+  rv = apr_file_close(f);
+  if (rv != APR_SUCCESS) {
+    ctx->set_error(ctx, GEOCACHE_DISK_ERROR, "failed to close file %s", lockname);
+    return;
+  }
+  tile->lock = NULL;
+}
+
+/**
+ * \brief query tile to check if the corresponding lockfile exists
+ * \sa geocache_cache::tile_lock()
+ * \sa geocache_cache::tile_unlock()
+ */
+int geocache_tileset_tile_lock_exists(geocache_context *ctx, geocache_tile *tile) {
+  char *lockname;
+  apr_file_t *f;
+  if (tile->lock)
+    return GEOCACHE_TRUE;
+  lockname = geocache_tileset_tile_lock_key(ctx, tile);
+  if (apr_file_open(&f, lockname, APR_FOPEN_READ, APR_OS_DEFAULT, ctx->pool) != APR_SUCCESS) {
+    return GEOCACHE_FALSE;
+  } else {
+    apr_file_close(f);
+    return GEOCACHE_TRUE;
+  }
+}
+
+/**
+ * \brief wait for a lock on given tile
+ *
+ * this function will not return until the lock on the tile has been removed
+ * \sa geocache_cache::tile_lock_wait()
+ */
+void geocache_tileset_tile_lock_wait(geocache_context *ctx, geocache_tile *tile) {
+  char *lockname;
+  apr_file_t *f;
+#ifdef DEBUG
+  if (tile->lock) {
+    ctx->set_error(ctx, GEOCACHE_DISK_ERROR, "### BUG ### waiting for a lock we have created ourself");
+    return;
+  }
+#endif
+  lockname = geocache_tileset_tile_lock_key(ctx, tile);
+  if (apr_file_open(&f, lockname, APR_FOPEN_READ, APR_OS_DEFAULT, ctx->pool) != APR_SUCCESS) {
+    ctx->set_error(ctx, GEOCACHE_DISK_ERROR, "### BUG ### waiting for a lock on an unlocked file");
+    return;
+  }
+  apr_file_lock(f, APR_FLOCK_SHARED);
+  apr_file_close(f);
+}
+

Added: trunk/mapserver/mapcache/src/source_gdal.c
===================================================================
--- trunk/mapserver/mapcache/src/source_gdal.c	                        (rev 0)
+++ trunk/mapserver/mapcache/src/source_gdal.c	2011-08-26 11:03:57 UTC (rev 12169)
@@ -0,0 +1,102 @@
+#include "geocache.h"
+#include <libxml/tree.h>
+#include <apr_tables.h>
+#include <apr_strings.h>
+
+/**
+ * \private \memberof geocache_source_gdal
+ * \sa geocache_source::render_tile()
+ */
+void _geocache_source_gdal_render_tile(geocache_context *ctx, geocache_tile *tile) {
+   geocache_source_gdal *gdal = (geocache_source_gdal*)tile->tileset->source;
+   apr_table_t *params = apr_table_clone(ctx->pool,gdal->gdal_default_params);
+   double bbox[4];
+   geocache_tileset_tile_bbox(tile,bbox);
+   apr_table_setn(params,"BBOX",apr_psprintf(ctx->pool,"%f,%f,%f,%f",bbox[0],bbox[1],bbox[2],bbox[3]));
+   apr_table_setn(params,"WIDTH",apr_psprintf(ctx->pool,"%d",tile->sx));
+   apr_table_setn(params,"HEIGHT",apr_psprintf(ctx->pool,"%d",tile->sy));
+   apr_table_setn(params,"FORMAT","image/png");
+   apr_table_setn(params,"SRS",tile->tileset->srs);
+   
+   apr_table_overlap(params,gdal->gdal_params,0);
+        
+   tile->data = geocache_buffer_create(1000,ctx->pool);
+   geocache_http_request_url_with_params(ctx,gdal->url,params,tile->data);
+}
+
+/**
+ * \private \memberof geocache_source_gdal
+ * \sa geocache_source::render_metatile()
+ */
+void _geocache_source_gdal_render_metatile(geocache_context *ctx, geocache_metatile *tile) {
+   geocache_source_gdal *gdal = (geocache_source_gdal*)tile->tile.tileset->source;
+   
+   apr_table_overlap(params,gdal->gdal_params,0);
+        
+   tile->tile.data = geocache_buffer_create(30000,ctx->pool);
+   geocache_http_request_url_with_params(ctx,gdal->url,params,tile->tile.data);
+   GC_CHECK_ERROR(ctx);
+   
+   if(!geocache_imageio_is_valid_format(ctx,tile->tile.data)) {
+      ctx->set_error(ctx, GEOCACHE_SOURCE_GDAL, "gdal request failed for tileset %s: %d %d %d returned an unsupported format",
+            tile->tile.tileset->name, tile->tile.x, tile->tile.y, tile->tile.z);
+   }
+}
+
+/**
+ * \private \memberof geocache_source_gdal
+ * \sa geocache_source::configuration_parse()
+ */
+void _geocache_source_gdal_configuration_parse(geocache_context *ctx, xmlNode *xml, geocache_source *source) {
+   xmlNode *cur_node;
+   geocache_source_gdal *src = (geocache_source_gdal*)source;
+   for(cur_node = xml->children; cur_node; cur_node = cur_node->next) {
+      if(cur_node->type != XML_ELEMENT_NODE) continue;
+      if(!xmlStrcmp(cur_node->name, BAD_CAST "data")) {
+         char* value = (char*)xmlNodeGetContent(cur_node);
+         src->data = value;
+      } else if(!xmlStrcmp(cur_node->name, BAD_CAST "options")) {
+         xmlNode *param_node;
+         for(param_node = cur_node->children; param_node; param_node = param_node->next) {
+            char *key,*value;
+            if(param_node->type != XML_ELEMENT_NODE) continue;
+            value = (char*)xmlNodeGetContent(param_node);
+            key = apr_pstrdup(ctx->pool, (char*)param_node->name);
+            apr_table_setn(src->gdal_params, key, value);
+         }
+      }
+   }
+}
+
+/**
+ * \private \memberof geocache_source_gdal
+ * \sa geocache_source::configuration_check()
+ */
+void _geocache_source_gdal_configuration_check(geocache_context *ctx, geocache_source *source) {
+   geocache_source_gdal *src = (geocache_source_gdal*)source;
+   /* check all required parameters are configured */
+   if(!strlen(src->data)) {
+      ctx->set_error(ctx, GEOCACHE_SOURCE_GDAL, "gdal source %s has no data",source->name);
+   }
+   /* TODO: open source and check it accepts given options */
+}
+
+geocache_source* geocache_source_gdal_create(geocache_context *ctx) {
+   geocache_source_gdal *source = apr_pcalloc(ctx->pool, sizeof(geocache_source_gdal));
+   if(!source) {
+      ctx->set_error(ctx, GEOCACHE_ALLOC_ERROR, "failed to allocate gdal source");
+      return NULL;
+   }
+   geocache_source_init(ctx, &(source->source));
+   source->source.type = GEOCACHE_SOURCE_GDAL;
+   source->source.supports_metatiling = 1;
+   source->source.render_tile = _geocache_source_gdal_render_tile;
+   source->source.render_metatile = _geocache_source_gdal_render_metatile;
+   source->source.configuration_check = _geocache_source_gdal_configuration_check;
+   source->source.configuration_parse = _geocache_source_gdal_configuration_parse;
+   source->options = apr_table_make(ctx->pool,4);
+   return (geocache_source*)source;
+}
+
+
+

Modified: trunk/mapserver/mapcache/src/tileset.c
===================================================================
--- trunk/mapserver/mapcache/src/tileset.c	2011-08-26 11:03:51 UTC (rev 12168)
+++ trunk/mapserver/mapcache/src/tileset.c	2011-08-26 11:03:57 UTC (rev 12169)
@@ -66,13 +66,13 @@
    int i;
    for(i=0; i<mt->ntiles; i++) {
       geocache_tile *tile = &(mt->tiles[i]);
-      mt->tile.tileset->cache->tile_lock(ctx, tile);
+      geocache_tileset_tile_lock(ctx, tile);
       if(GC_HAS_ERROR(ctx)) {
          /* undo successful locks */
          int j;
          for(j=0;j<i;j++) {
             tile = &(mt->tiles[j]);
-            mt->tile.tileset->cache->tile_unlock(ctx,tile);
+            geocache_tileset_tile_unlock(ctx,tile);
          }
       }
    }
@@ -85,7 +85,7 @@
    int i;
    for(i=0; i<mt->ntiles; i++) {
       geocache_tile *tile = &(mt->tiles[i]);
-      mt->tile.tileset->cache->tile_unlock(ctx, tile);
+      geocache_tileset_tile_unlock(ctx, tile);
    }
 }
 
@@ -175,6 +175,7 @@
    tileset->extent[0]=tileset->extent[1]=tileset->extent[2]=tileset->extent[3]=0;
    tileset->forwarded_params = apr_table_make(ctx->pool,1);
    tileset->format = NULL;
+   tileset->config = NULL;
    return tileset;
 }
 
@@ -244,7 +245,7 @@
       ctx->global_lock_aquire(ctx,0);
       GC_CHECK_ERROR(ctx);
 
-      isLocked = tile->tileset->cache->tile_lock_exists(ctx, tile);
+      isLocked = geocache_tileset_tile_lock_exists(ctx, tile);
       if(isLocked == GEOCACHE_FALSE) {
          /* no other thread is doing the rendering, we aquire and lock a list of tiles to render */
          mt = _geocache_tileset_metatile_get(ctx, tile);
@@ -261,7 +262,7 @@
          ctx->log(ctx, GEOCACHE_DEBUG, "cache wait: tileset %s - tile %d %d %d",
                tile->tileset->name,tile->x, tile->y,tile->z);
 #endif
-         tile->tileset->cache->tile_lock_wait(ctx,tile);
+         geocache_tileset_tile_lock_wait(ctx,tile);
          GC_CHECK_ERROR(ctx);
       } else {
          /* no other thread is doing the rendering, do it ourselves */



More information about the mapserver-commits mailing list