<br><font size=2 face="sans-serif">Tamas, Umberto</font>
<br>
<br><font size=2 face="sans-serif">Umberto wrote about good experience
with Mapserver-Multithreading in Java.</font>
<br><font size=2 face="sans-serif">This is not my experience. In our "Mapserver-Servlet"
we had to use a global synchronizing around</font>
<br><font size=2 face="sans-serif">mapserver-calls (i.e. disabling
multithreading) to avoid crashes. </font>
<br>
<br><font size=2 face="sans-serif">Benedikt</font>
<br>
<br><font size=2><tt>UMN MapServer Developers List <MAPSERVER-DEV@LISTS.UMN.EDU>
schrieb am 08.08.2006 17:42:22:<br>
<br>
> Tamas,<br>
> I have a few applications built with Java mapscript (shape and raster,<br>
> so not much really) and they seem to work very well. Years ago (when<br>
> mapscript was in its infancy) I performed massive load testing and
at<br>
> that time I did not experience problems at all.<br>
> <br>
> More recently I have been running the thread test in mapscript/java<br>
> against both the standard test map and a map built against oracle<br>
> without any problem. Performance was not taken into account, only<br>
> correctness.<br>
> <br>
> Umberto<br>
> <br>
> On 8/8/06, Tamas Szekeres <szekerest@gmail.com> wrote:<br>
> > Steve,<br>
> ><br>
> > As digging into the problem increasingly i am getting more and
more<br>
> > disappointed. By now i am not sure whether mapscript is safe
for<br>
> > multithreading at all (even if thread support is switched on).<br>
> > For example the most essential gd library uses a number of static<br>
> > variables without using any protection when accessing them. The
proj<br>
> > library also has a number of static variables an we have protection<br>
> > only against pj_init in the mapserver code. For example i am<br>
> > considering pj_transform is unsafe as well (as using static
pj_errno<br>
> > for example).<br>
> ><br>
> > The problems existing in the libraries cause the same issues
as if<br>
> > they were in the mapserver code directly. Each of the dll is
loaded<br>
> > into the process "globally" so any static variable
becomes processwide<br>
> > global variable.<br>
> > Has anyone reviewed the libraries with this regard?<br>
> ><br>
> > I have collected the potential problems of the two libraries
mentioned<br>
> > before. Some of the variables might be const static not causing
such<br>
> > problems, apologies for those.<br>
> ><br>
> > In the gd library:<br>
> ><br>
> > gd-2.0.33\gd_gif_in.c(12):static int verbose_set = 0;<br>
> > gd-2.0.33\gd_gif_in.c(13):static int verbose;<br>
> > gd-2.0.33\gd_gif_in.c(68):} Gif89 = { -1, -1, -1, 0 };<br>
> > gd-2.0.33\gd_gif_in.c(244): static unsigned
char buf[256];<br>
> > gd-2.0.33\gd_gif_in.c(308): static unsigned
char buf[280];<br>
> > gd-2.0.33\gd_gif_in.c(309): static int
curbit,<br>
> > lastbit, done, last_byte;<br>
> > gd-2.0.33\gd_gif_in.c(360): static int
fresh = FALSE;<br>
> > gd-2.0.33\gd_gif_in.c(362): static int
code_size, set_code_size;<br>
> > gd-2.0.33\gd_gif_in.c(363): static int
max_code, max_code_size;<br>
> > gd-2.0.33\gd_gif_in.c(364): static int
firstcode, oldcode;<br>
> > gd-2.0.33\gd_gif_in.c(365): static int
clear_code, end_code;<br>
> > gd-2.0.33\gd_gif_in.c(366): static int
table[2][(1<< MAX_LWZ_BITS)];<br>
> > gd-2.0.33\gd_gif_in.c(367): static int
stack[STACK_SIZE], *sp;<br>
> > gd-2.0.33\gd_png.c(50):static jmpbuf_wrapper gdPngJmpbufStruct;<br>
> > gd-2.0.33\gdft.c(31):static int fontConfigFlag = 0;<br>
> > gd-2.0.33\gdft.c(777):static gdCache_head_t *fontCache;<br>
> > gd-2.0.33\gdft.c(778):static FT_Library library;<br>
> > gd-2.0.33\gdkanji.c(120): static int whatcode = ASCII;<br>
> > gd-2.0.33\gdkanji.c(499): static unsigned char tmp[BUFSIZ];<br>
> > gd-2.0.33\gdkanji.c(595): static unsigned char tmp_dest[BUFSIZ];<br>
> ><br>
> > In the proj library:<br>
> ><br>
> > proj-4.4.9\src\biveval.c(7): static projUV<br>
> > proj-4.4.9\src\cs2cs.c(69):static projPJ fromProj, toProj;<br>
> > proj-4.4.9\src\cs2cs.c(71):static int<br>
> > proj-4.4.9\src\cs2cs.c(76): static char<br>
> > proj-4.4.9\src\cs2cs.c(83):static struct FACTORS facs;<br>
> > proj-4.4.9\src\cs2cs.c(84):static double (*informat)(const char
*,<br>
> > proj-4.4.9\src\geod.c(15): static int<br>
> > proj-4.4.9\src\geod.c(20): static char<br>
> > proj-4.4.9\src\geod.c(129):static char *pargv[MAX_PARGS];<br>
> > proj-4.4.9\src\geod.c(130):static int pargc = 0;<br>
> > proj-4.4.9\src\geod.c(135): static int eargc =
0, c;<br>
> > proj-4.4.9\src\geod_for.c(7): static double<br>
> > proj-4.4.9\src\geod_for.c(9): static int<br>
> > proj-4.4.9\src\nad2nad.c(16): static int<br>
> > proj-4.4.9\src\nad2nad.c(19): static char<br>
> > proj-4.4.9\src\nad2nad.c(54):} input = {<br>
> > proj-4.4.9\src\nad2nad.c(58):}, output = {<br>
> > proj-4.4.9\src\pj_apply_gridshift.c(79): static
int debug_count = 0;<br>
> > proj-4.4.9\src\pj_gridinfo.c(66):static int byte_order_test
= 1;<br>
> > proj-4.4.9\src\pj_gridlist.c(50):static PJ_GRIDINFO *grid_list
= NULL;<br>
> > proj-4.4.9\src\pj_gridlist.c(54):static int
last_nadgrids_max = 0;<br>
> > proj-4.4.9\src\pj_gridlist.c(55):static int
last_nadgrids_count = 0;<br>
> > proj-4.4.9\src\pj_gridlist.c(56):static PJ_GRIDINFO **last_nadgrids_list
= NULL;<br>
> > proj-4.4.9\src\pj_gridlist.c(57):static char
*last_nadgrids = NULL;<br>
> > proj-4.4.9\src\pj_init.c(71):static paralist *start;<br>
> > proj-4.4.9\src\PJ_mod_ster.c(102): static
COMPLEX /* Miller Oblated<br>
> > Stereographic */<br>
> > proj-4.4.9\src\PJ_mod_ster.c(116): static
COMPLEX /* Lee Oblated<br>
> > Stereographic */<br>
> > proj-4.4.9\src\PJ_mod_ster.c(130): static
COMPLEX /* 48 United States */<br>
> > proj-4.4.9\src\PJ_mod_ster.c(147): static
COMPLEX<br>
> > proj-4.4.9\src\PJ_mod_ster.c(177): static
COMPLEX<br>
> > proj-4.4.9\src\PJ_nzmg.c(48): static COMPLEX<br>
> > proj-4.4.9\src\PJ_nzmg.c(56): static double<br>
> > proj-4.4.9\src\pj_open_lib.c(51):static int path_count = 0;<br>
> > proj-4.4.9\src\pj_open_lib.c(52):static char **search_path =
NULL;<br>
> > proj-4.4.9\src\pj_open_lib.c(53):static char * proj_lib_name
=<br>
> > proj-4.4.9\src\PJ_robin.c(10):static struct COEFS {<br>
> > proj-4.4.9\src\pj_strerrno.c(61): static char note[50];<br>
> > proj-4.4.9\src\proj.c(26): static PJ<br>
> > proj-4.4.9\src\proj.c(28): static projUV<br>
> > proj-4.4.9\src\proj.c(30): static int<br>
> > proj-4.4.9\src\proj.c(43): static char<br>
> > proj-4.4.9\src\proj.c(49): static struct
FACTORS<br>
> > proj-4.4.9\src\proj.c(51): static double<br>
> > proj-4.4.9\src\rtodms.c(13): static double<br>
> > proj-4.4.9\src\rtodms.c(17): static char<br>
> > proj-4.4.9\src\rtodms.c(19): static int<br>
> > proj-4.4.9\src\pj_datums.c(73):C_NAMESPACE struct PJ_DATUMS pj_datums[]
= {<br>
> > proj-4.4.9\src\pj_datums.c(98):C_NAMESPACE struct PJ_PRIME_MERIDIANS<br>
> > pj_prime_meridians[] = {<br>
> > proj-4.4.9\src\pj_ellps.c(8):C_NAMESPACE struct PJ_ELLPS<br>
> > proj-4.4.9\src\pj_errno.c(8):C_NAMESPACE int pj_errno = 0;<br>
> > proj-4.4.9\src\PJ_goode.c(10): C_NAMESPACE PJ<br>
> > proj-4.4.9\src\pj_units.c(10):C_NAMESPACE struct PJ_UNITS<br>
> ><br>
> ><br>
> > I wonder if mapscript can safely be used in a real multithreaded<br>
> > environment regardless of the performance problems. Are there
any<br>
> > further experiences about this issue? Which architecture can
be used?<br>
> > I cannot step beyond the "one process handles one request
at a time"<br>
> > model.<br>
> ><br>
> ><br>
> > Best Regards,<br>
> ><br>
> > Tamas<br>
> ><br>
> ><br>
> > 2006/8/8, Steve Lime <Steve.Lime@dnr.state.mn.us>:<br>
> > > Tamas: What happened to the talk of thread specific globals
that<br>
> > > was started on mapserver-dev awhile back? Now's the time
to move<br>
> > > on such things...<br>
> > ><br>
> > > Steve<br>
> > ><br>
> > > >>> Tamas Szekeres <szekerest@GMAIL.COM>
8/7/2006 3:22:16 PM >>><br>
> > > Hi,<br>
> > ><br>
> > > Many of the mapserver components use globally allocated
data so<br>
> > > multiple threads within the executable (inside libmap.dll
in this<br>
> > > case) share the same data.<br>
> > > Moreover the .dll is loaded into the host application (eg.<br>
> > > aspnet_wp.exe or w3wp.exe) and the global variable will
be shared<br>
> > > among the threads within the overall worker process.<br>
> > > The process may host multiple appdomains so the variables
is shared<br>
> > > among multiple web applications in this case. Lastly, the
ASP<br>
> > > application model implies the various requests are handled
by multiple<br>
> > > threads taken out of a pool of threads.<br>
> > ><br>
> > > It seems terrible compared to the architecture of a windows<br>
> > > application, isn't it?<br>
> > ><br>
> > > If mapserver is compiled with thread support the global
data in some<br>
> > > of the components are protected by locks to provide synchronized<br>
> > > access by multiple threads. The access will take place sequentially
so<br>
> > > the threads will wait for each<br>
> > > other. For example if you are creating mapObj from a .map
file<br>
> > > multiple requests will wait for each other when parsing
the file. This<br>
> > > kind of thread interaction may be slightly decreased if
the protected<br>
> > > critical sections could be made smaller.<br>
> > ><br>
> > > The issue mentioned previously makes some of us frustrated.<br>
> > > Maintaining locks kills the performance of the application,
it would<br>
> > > be preferable to avoid the global data at all when possible.<br>
> > > Unfortunately to achieve this level much of the code should
be<br>
> > > reconsidered ( a better sort of collaboration should be
made between<br>
> > > the developers ).<br>
> > ><br>
> > > I consider this problem is critical and will manifest itself
more and<br>
> > > more obviously. I wonder the other mapscript languages are
living<br>
> > > happily without it ;-)<br>
> > ><br>
> > > Getting back to your question this time i would prefer establishing<br>
> > > the mapping functionality in the middleware if possible.
The drawing<br>
> > > request should be queued and a pool of multiple processes
should be<br>
> > > spawned to handle the requests. The result may be dispatched
back to<br>
> > > the client using HTTP. The MONO XSP implementation may also
help to<br>
> > > establish the required functionality.<br>
> > ><br>
> > > Best Regards,<br>
> > ><br>
> > ><br>
> > > Tamas Szekeres<br>
> > ><br>
> > ><br>
> > ><br>
> > ><br>
> > > 2006/8/7, Zhonghai Wang <zhonghaiw@gmail.com>:<br>
> > > ><br>
> > > > Hi All,<br>
> > > ><br>
> > > > I've developed a windows application with the C# MapScript,
and this<br>
> > > > application works well with all the common mapping
functions. I am<br>
> > > very<br>
> > > > happy with the performance of MapServer. So I am now
trying to<br>
> > > migrate the<br>
> > > > windows application to a web application, here
I have some doubts<br>
> > > with the<br>
> > > > migration:<br>
> > > ><br>
> > > > 1. for the windows application I use a singelton class
to return the<br>
> > > mapobj<br>
> > > > for all the mapping API -- I've programmed a
mapping class for<br>
> > > mapping<br>
> > > > functionalities, and this works well to store all the
changes of a<br>
> > > mapobj<br>
> > > > during the mapping process. But if I migrate the mapping
class to<br>
> > > web<br>
> > > > application, this singelton class should not be used,
since there may<br>
> > > be<br>
> > > > hundred users, who are accessing MapServer at the same
time. I am<br>
> > > just<br>
> > > > wondering how to solve this problem in MapServer?<br>
> > > ><br>
> > > > In MapXtreme, this problem is solved with the use of
MapXBroker,<br>
> > > which is a<br>
> > > > shared pool of MapX objects, does MapServer has any
similar<br>
> > > component?<br>
> > > ><br>
> > > > 2. Thread-Safety, I know this is not a new question,
but it's<br>
> > > important. In<br>
> > > > the .NET application, how to solve this problem? use
thread lock? (I<br>
> > > am<br>
> > > > programming with VB.NET)<br>
> > > ><br>
> > > > thanks for any information about this topic.<br>
> > > ><br>
> > > ><br>
> > > > zhonghai<br>
> > ><br>
> ><br>
</tt></font>