diff options
| author | Even Rouault <even.rouault@mines-paris.org> | 2014-08-19 12:01:05 +0000 |
|---|---|---|
| committer | Even Rouault <even.rouault@mines-paris.org> | 2014-08-19 12:01:05 +0000 |
| commit | 30d531eb65b988c11f351044d0ec8079f221725f (patch) | |
| tree | 90c8d0de0e41969c66d403d8bc78df2f34bfce70 | |
| parent | 00c78fb9eb30356c03bcc822bb14a2079e725eb3 (diff) | |
| download | PROJ-30d531eb65b988c11f351044d0ec8079f221725f.tar.gz PROJ-30d531eb65b988c11f351044d0ec8079f221725f.zip | |
Make pj_gridinfo_load() thread-safe (#228)
git-svn-id: http://svn.osgeo.org/metacrs/proj/trunk@2488 4e78687f-474d-0410-85f9-8d5e500ac6b2
| -rw-r--r-- | ChangeLog | 4 | ||||
| -rw-r--r-- | src/Makefile.am | 4 | ||||
| -rw-r--r-- | src/Makefile.in | 64 | ||||
| -rw-r--r-- | src/pj_gridinfo.c | 68 | ||||
| -rw-r--r-- | src/test228.c | 70 |
5 files changed, 169 insertions, 41 deletions
@@ -1,3 +1,7 @@ +2014-19-08 Even Rouault <even.rouault@mines-paris.org> + + * src/pj_gridinfo.c: Make pj_gridinfo_load() thread-safe (#228) + 2014-19-08 Howard Butler <hobu.inc@gmail.com> * src/pj_init.c: apply fix specified in #229 -- pj_init_plus() with init diff --git a/src/Makefile.am b/src/Makefile.am index a47d832f..50eb416b 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,7 +1,7 @@ AM_CFLAGS = @C_WFLAGS@ bin_PROGRAMS = proj nad2bin geod cs2cs -EXTRA_PROGRAMS = multistresstest +EXTRA_PROGRAMS = multistresstest test228 INCLUDES = -DPROJ_LIB=\"$(pkgdatadir)\" \ -DMUTEX_@MUTEX_SETTING@ @JNI_INCLUDE@ @@ -16,12 +16,14 @@ cs2cs_SOURCES = cs2cs.c gen_cheb.c p_series.c nad2bin_SOURCES = nad2bin.c geod_SOURCES = geod.c geod_set.c geod_interface.c geod_interface.h multistresstest_SOURCES = multistresstest.c +test228_SOURCES = test228.c proj_LDADD = libproj.la cs2cs_LDADD = libproj.la nad2bin_LDADD = libproj.la geod_LDADD = libproj.la multistresstest_LDADD = libproj.la -lpthread +test228_LDADD = libproj.la -lpthread lib_LTLIBRARIES = libproj.la diff --git a/src/Makefile.in b/src/Makefile.in index 619747e2..bd95c6a7 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -1,9 +1,9 @@ -# Makefile.in generated by automake 1.11.1 from Makefile.am. +# Makefile.in generated by automake 1.11.3 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, -# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, -# Inc. +# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software +# Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. @@ -38,7 +38,7 @@ build_triplet = @build@ host_triplet = @host@ bin_PROGRAMS = proj$(EXEEXT) nad2bin$(EXEEXT) geod$(EXEEXT) \ cs2cs$(EXEEXT) -EXTRA_PROGRAMS = multistresstest$(EXEEXT) +EXTRA_PROGRAMS = multistresstest$(EXEEXT) test228$(EXEEXT) subdir = src DIST_COMMON = $(include_HEADERS) $(srcdir)/Makefile.am \ $(srcdir)/Makefile.in $(srcdir)/proj_config.h.in @@ -74,6 +74,12 @@ am__nobase_list = $(am__nobase_strip_setup); \ am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(bindir)" \ "$(DESTDIR)$(includedir)" LTLIBRARIES = $(lib_LTLIBRARIES) @@ -133,6 +139,9 @@ nad2bin_DEPENDENCIES = libproj.la am_proj_OBJECTS = proj.$(OBJEXT) gen_cheb.$(OBJEXT) p_series.$(OBJEXT) proj_OBJECTS = $(am_proj_OBJECTS) proj_DEPENDENCIES = libproj.la +am_test228_OBJECTS = test228.$(OBJEXT) +test228_OBJECTS = $(am_test228_OBJECTS) +test228_DEPENDENCIES = libproj.la DEFAULT_INCLUDES = -I.@am__isrc@ depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles @@ -147,9 +156,11 @@ LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ $(LDFLAGS) -o $@ SOURCES = $(libproj_la_SOURCES) $(cs2cs_SOURCES) $(geod_SOURCES) \ - $(multistresstest_SOURCES) $(nad2bin_SOURCES) $(proj_SOURCES) + $(multistresstest_SOURCES) $(nad2bin_SOURCES) $(proj_SOURCES) \ + $(test228_SOURCES) DIST_SOURCES = $(libproj_la_SOURCES) $(cs2cs_SOURCES) $(geod_SOURCES) \ - $(multistresstest_SOURCES) $(nad2bin_SOURCES) $(proj_SOURCES) + $(multistresstest_SOURCES) $(nad2bin_SOURCES) $(proj_SOURCES) \ + $(test228_SOURCES) HEADERS = $(include_HEADERS) ETAGS = etags CTAGS = ctags @@ -284,11 +295,13 @@ cs2cs_SOURCES = cs2cs.c gen_cheb.c p_series.c nad2bin_SOURCES = nad2bin.c geod_SOURCES = geod.c geod_set.c geod_interface.c geod_interface.h multistresstest_SOURCES = multistresstest.c +test228_SOURCES = test228.c proj_LDADD = libproj.la cs2cs_LDADD = libproj.la nad2bin_LDADD = libproj.la geod_LDADD = libproj.la multistresstest_LDADD = libproj.la -lpthread +test228_LDADD = libproj.la -lpthread lib_LTLIBRARIES = libproj.la libproj_la_LDFLAGS = -no-undefined -version-info 8:0:8 libproj_la_SOURCES = \ @@ -369,10 +382,8 @@ $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) $(am__aclocal_m4_deps): proj_config.h: stamp-h1 - @if test ! -f $@; then \ - rm -f stamp-h1; \ - $(MAKE) $(AM_MAKEFLAGS) stamp-h1; \ - else :; fi + @if test ! -f $@; then rm -f stamp-h1; else :; fi + @if test ! -f $@; then $(MAKE) $(AM_MAKEFLAGS) stamp-h1; else :; fi stamp-h1: $(srcdir)/proj_config.h.in $(top_builddir)/config.status @rm -f stamp-h1 @@ -415,7 +426,7 @@ clean-libLTLIBRARIES: echo "rm -f \"$${dir}/so_locations\""; \ rm -f "$${dir}/so_locations"; \ done -libproj.la: $(libproj_la_OBJECTS) $(libproj_la_DEPENDENCIES) +libproj.la: $(libproj_la_OBJECTS) $(libproj_la_DEPENDENCIES) $(EXTRA_libproj_la_DEPENDENCIES) $(libproj_la_LINK) -rpath $(libdir) $(libproj_la_OBJECTS) $(libproj_la_LIBADD) $(LIBS) install-binPROGRAMS: $(bin_PROGRAMS) @$(NORMAL_INSTALL) @@ -460,21 +471,24 @@ clean-binPROGRAMS: list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ echo " rm -f" $$list; \ rm -f $$list -cs2cs$(EXEEXT): $(cs2cs_OBJECTS) $(cs2cs_DEPENDENCIES) +cs2cs$(EXEEXT): $(cs2cs_OBJECTS) $(cs2cs_DEPENDENCIES) $(EXTRA_cs2cs_DEPENDENCIES) @rm -f cs2cs$(EXEEXT) $(LINK) $(cs2cs_OBJECTS) $(cs2cs_LDADD) $(LIBS) -geod$(EXEEXT): $(geod_OBJECTS) $(geod_DEPENDENCIES) +geod$(EXEEXT): $(geod_OBJECTS) $(geod_DEPENDENCIES) $(EXTRA_geod_DEPENDENCIES) @rm -f geod$(EXEEXT) $(LINK) $(geod_OBJECTS) $(geod_LDADD) $(LIBS) -multistresstest$(EXEEXT): $(multistresstest_OBJECTS) $(multistresstest_DEPENDENCIES) +multistresstest$(EXEEXT): $(multistresstest_OBJECTS) $(multistresstest_DEPENDENCIES) $(EXTRA_multistresstest_DEPENDENCIES) @rm -f multistresstest$(EXEEXT) $(LINK) $(multistresstest_OBJECTS) $(multistresstest_LDADD) $(LIBS) -nad2bin$(EXEEXT): $(nad2bin_OBJECTS) $(nad2bin_DEPENDENCIES) +nad2bin$(EXEEXT): $(nad2bin_OBJECTS) $(nad2bin_DEPENDENCIES) $(EXTRA_nad2bin_DEPENDENCIES) @rm -f nad2bin$(EXEEXT) $(LINK) $(nad2bin_OBJECTS) $(nad2bin_LDADD) $(LIBS) -proj$(EXEEXT): $(proj_OBJECTS) $(proj_DEPENDENCIES) +proj$(EXEEXT): $(proj_OBJECTS) $(proj_DEPENDENCIES) $(EXTRA_proj_DEPENDENCIES) @rm -f proj$(EXEEXT) $(LINK) $(proj_OBJECTS) $(proj_LDADD) $(LIBS) +test228$(EXEEXT): $(test228_OBJECTS) $(test228_DEPENDENCIES) $(EXTRA_test228_DEPENDENCIES) + @rm -f test228$(EXEEXT) + $(LINK) $(test228_OBJECTS) $(test228_LDADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) @@ -645,6 +659,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/proj_mdist.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/proj_rouss.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rtodms.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test228.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vector1.Plo@am__quote@ .c.o: @@ -690,9 +705,7 @@ uninstall-includeHEADERS: @$(NORMAL_UNINSTALL) @list='$(include_HEADERS)'; test -n "$(includedir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ - test -n "$$files" || exit 0; \ - echo " ( cd '$(DESTDIR)$(includedir)' && rm -f" $$files ")"; \ - cd "$(DESTDIR)$(includedir)" && rm -f $$files + dir='$(DESTDIR)$(includedir)'; $(am__uninstall_files_from_dir) ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ @@ -795,10 +808,15 @@ install-am: all-am installcheck: installcheck-am install-strip: - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - `test -z '$(STRIP)' || \ - echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi mostlyclean-generic: clean-generic: diff --git a/src/pj_gridinfo.c b/src/pj_gridinfo.c index 3ce7ecd3..c90e5734 100644 --- a/src/pj_gridinfo.c +++ b/src/pj_gridinfo.c @@ -118,8 +118,19 @@ void pj_gridinfo_free( projCtx ctx, PJ_GRIDINFO *gi ) int pj_gridinfo_load( projCtx ctx, PJ_GRIDINFO *gi ) { + struct CTABLE ct_tmp; + if( gi == NULL || gi->ct == NULL ) return 0; + + pj_acquire_lock(); + if( gi->ct->cvs != NULL ) + { + pj_release_lock(); + return 1; + } + + memcpy(&ct_tmp, gi->ct, sizeof(struct CTABLE)); /* -------------------------------------------------------------------- */ /* Original platform specific CTable format. */ @@ -134,13 +145,17 @@ int pj_gridinfo_load( projCtx ctx, PJ_GRIDINFO *gi ) if( fid == NULL ) { pj_ctx_set_errno( ctx, -38 ); + pj_release_lock(); return 0; } - result = nad_ctable_load( ctx, gi->ct, fid ); + result = nad_ctable_load( ctx, &ct_tmp, fid ); pj_ctx_fclose( ctx, fid ); + gi->ct->cvs = ct_tmp.cvs; + pj_release_lock(); + return result; } @@ -157,13 +172,17 @@ int pj_gridinfo_load( projCtx ctx, PJ_GRIDINFO *gi ) if( fid == NULL ) { pj_ctx_set_errno( ctx, -38 ); + pj_release_lock(); return 0; } - result = nad_ctable2_load( ctx, gi->ct, fid ); + result = nad_ctable2_load( ctx, &ct_tmp, fid ); pj_ctx_fclose( ctx, fid ); + gi->ct->cvs = ct_tmp.cvs; + + pj_release_lock(); return result; } @@ -185,16 +204,18 @@ int pj_gridinfo_load( projCtx ctx, PJ_GRIDINFO *gi ) if( fid == NULL ) { pj_ctx_set_errno( ctx, -38 ); + pj_release_lock(); return 0; } pj_ctx_fseek( ctx, fid, gi->grid_offset, SEEK_SET ); row_buf = (double *) pj_malloc(gi->ct->lim.lam * sizeof(double) * 2); - gi->ct->cvs = (FLP *) pj_malloc(gi->ct->lim.lam*gi->ct->lim.phi*sizeof(FLP)); - if( row_buf == NULL || gi->ct->cvs == NULL ) + ct_tmp.cvs = (FLP *) pj_malloc(gi->ct->lim.lam*gi->ct->lim.phi*sizeof(FLP)); + if( row_buf == NULL || ct_tmp.cvs == NULL ) { pj_ctx_set_errno( ctx, -38 ); + pj_release_lock(); return 0; } @@ -209,7 +230,7 @@ int pj_gridinfo_load( projCtx ctx, PJ_GRIDINFO *gi ) != 2 * gi->ct->lim.lam ) { pj_dalloc( row_buf ); - pj_dalloc( gi->ct->cvs ); + pj_dalloc( ct_tmp.cvs ); pj_ctx_set_errno( ctx, -38 ); return 0; } @@ -222,7 +243,7 @@ int pj_gridinfo_load( projCtx ctx, PJ_GRIDINFO *gi ) for( i = 0; i < gi->ct->lim.lam; i++ ) { - cvs = gi->ct->cvs + (row) * gi->ct->lim.lam + cvs = ct_tmp.cvs + (row) * gi->ct->lim.lam + (gi->ct->lim.lam - i - 1); cvs->phi = *(diff_seconds++) * ((PI/180.0) / 3600.0); @@ -234,6 +255,9 @@ int pj_gridinfo_load( projCtx ctx, PJ_GRIDINFO *gi ) pj_ctx_fclose( ctx, fid ); + gi->ct->cvs = ct_tmp.cvs; + pj_release_lock(); + return 1; } @@ -258,16 +282,18 @@ int pj_gridinfo_load( projCtx ctx, PJ_GRIDINFO *gi ) if( fid == NULL ) { pj_ctx_set_errno( ctx, -38 ); + pj_release_lock(); return 0; } pj_ctx_fseek( ctx, fid, gi->grid_offset, SEEK_SET ); row_buf = (float *) pj_malloc(gi->ct->lim.lam * sizeof(float) * 4); - gi->ct->cvs = (FLP *) pj_malloc(gi->ct->lim.lam*gi->ct->lim.phi*sizeof(FLP)); - if( row_buf == NULL || gi->ct->cvs == NULL ) + ct_tmp.cvs = (FLP *) pj_malloc(gi->ct->lim.lam*gi->ct->lim.phi*sizeof(FLP)); + if( row_buf == NULL || ct_tmp.cvs == NULL ) { pj_ctx_set_errno( ctx, -38 ); + pj_release_lock(); return 0; } @@ -282,9 +308,9 @@ int pj_gridinfo_load( projCtx ctx, PJ_GRIDINFO *gi ) != 4 * gi->ct->lim.lam ) { pj_dalloc( row_buf ); - pj_dalloc( gi->ct->cvs ); - gi->ct->cvs = NULL; + pj_dalloc( ct_tmp.cvs ); pj_ctx_set_errno( ctx, -38 ); + pj_release_lock(); return 0; } @@ -297,7 +323,7 @@ int pj_gridinfo_load( projCtx ctx, PJ_GRIDINFO *gi ) for( i = 0; i < gi->ct->lim.lam; i++ ) { - cvs = gi->ct->cvs + (row) * gi->ct->lim.lam + cvs = ct_tmp.cvs + (row) * gi->ct->lim.lam + (gi->ct->lim.lam - i - 1); cvs->phi = *(diff_seconds++) * ((PI/180.0) / 3600.0); @@ -309,7 +335,10 @@ int pj_gridinfo_load( projCtx ctx, PJ_GRIDINFO *gi ) pj_dalloc( row_buf ); pj_ctx_fclose( ctx, fid ); + + gi->ct->cvs = ct_tmp.cvs; + pj_release_lock(); return 1; } @@ -326,35 +355,40 @@ int pj_gridinfo_load( projCtx ctx, PJ_GRIDINFO *gi ) if( fid == NULL ) { pj_ctx_set_errno( ctx, -38 ); + pj_release_lock(); return 0; } pj_ctx_fseek( ctx, fid, gi->grid_offset, SEEK_SET ); - gi->ct->cvs = (FLP *) pj_malloc(words*sizeof(float)); - if( gi->ct->cvs == NULL ) + ct_tmp.cvs = (FLP *) pj_malloc(words*sizeof(float)); + if( ct_tmp.cvs == NULL ) { pj_ctx_set_errno( ctx, -38 ); + pj_release_lock(); return 0; } - if( pj_ctx_fread( ctx, gi->ct->cvs, sizeof(float), words, fid ) + if( pj_ctx_fread( ctx, ct_tmp.cvs, sizeof(float), words, fid ) != words ) { - pj_dalloc( gi->ct->cvs ); - gi->ct->cvs = NULL; + pj_dalloc( ct_tmp.cvs ); + pj_release_lock(); return 0; } if( IS_LSB ) - swap_words( (unsigned char *) gi->ct->cvs, 4, words ); + swap_words( (unsigned char *) ct_tmp.cvs, 4, words ); pj_ctx_fclose( ctx, fid ); + gi->ct->cvs = ct_tmp.cvs; + pj_release_lock(); return 1; } else { + pj_release_lock(); return 0; } } diff --git a/src/test228.c b/src/test228.c new file mode 100644 index 00000000..464c5736 --- /dev/null +++ b/src/test228.c @@ -0,0 +1,70 @@ +#include <proj_api.h> + +#ifdef _WIN32 + +int main(int argc, char* argv[]) +{ + printf("Test not yet ported on Win32\n"); + return 0; +} + +#else + +#include <pthread.h> +#include <stdio.h> +#include <assert.h> +#include <unistd.h> + +volatile int go_on = 1; + +void* thread_main(void* unused) +{ + projCtx p_proj_ctxt; + projPJ p_WGS84_proj; + projPJ p_OSGB36_proj; + + p_proj_ctxt=pj_ctx_alloc(); + p_WGS84_proj=pj_init_plus_ctx(p_proj_ctxt,"+proj=longlat " + "+ellps=WGS84 +datum=WGS84 +no_defs"); + p_OSGB36_proj=pj_init_plus_ctx(p_proj_ctxt, + "+proj=longlat +ellps=airy +datum=OSGB36 +nadgrids=OSTN02_NTv2.gsb " + "+no_defs"); + + while(go_on) + { + double x, y; + int proj_ret; + + x = -5.2*DEG_TO_RAD; + y = 50*DEG_TO_RAD; + proj_ret = pj_transform(p_WGS84_proj, + p_OSGB36_proj, 1, 1, &x, &y, NULL ); + x *= RAD_TO_DEG; + y *= RAD_TO_DEG; + /*printf("%.18f %.18f\n", x, y); */ + assert(proj_ret == 0); + assert(fabs(x - -5.198965360936369962) < 1e-15); + assert(fabs(y - 49.999396034285531698) < 1e-15); + } + + return NULL; +} + +int main(int argc, char* argv[]) +{ + int i; + pthread_t tid1, tid2; + pthread_attr_t attr1, attr2; + + pthread_attr_init(&attr1); + pthread_attr_init(&attr2); + + pthread_create(&tid1, &attr1, thread_main, NULL); + pthread_create(&tid2, &attr2, thread_main, NULL); + for(i=0;i<2;i++) + sleep(1); + go_on = 0; + return 0; +} + +#endif /* _WIN32 */
\ No newline at end of file |
