aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog4
-rw-r--r--src/Makefile.am4
-rw-r--r--src/Makefile.in64
-rw-r--r--src/pj_gridinfo.c68
-rw-r--r--src/test228.c70
5 files changed, 169 insertions, 41 deletions
diff --git a/ChangeLog b/ChangeLog
index f0c9ad26..ee273c4e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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