axis-c-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Tim Bartley <tbart...@au1.ibm.com>
Subject RE: Possbile bug in Axis.cpp on Win32 (XP, VC7.1)
Date Tue, 12 Apr 2005 01:37:00 GMT
Hi,

Sorry for this confusion -  I forgot about this issue - been a while since 
I used VC6.

The prototype but not the behaviour of InterlockedCompareExchange changed 
between VC 6 and 7. Semantically, tte correct code is as per the patch I 
submitted - values of the comparand and exchangand should be passed by 
value not reference. The VC6 prototype simply assumed "void*" was a good 
alias for "32-bit value" - VC7 corrected this.

To get it to compile under VC6 the correct (extremely ugly) change would 
be simply:

while (InterlockedCompareExchange((void **)&g_uModuleInitializing, 
(void*)1, (void *) 0));

but this would of course still break VC7 compiles.

To get code that will compiler under either it's probably better to simply 
use InterlockedIncrement/Decrement for this stuff.

The implementation of start_initializing/done_initializing should compile 
on both but may generate warnings on VC6 because VC6's prototypes don't 
use "volatile".

static volatile long g_uModuleInitializing = 0;
static void start_initializing()
{
    while (InterlockedIncrement(&g_uModuleInitializing) != 1) {
        InterlockedDecrement(&g_uModuleInitializing);
    }
}
static void done_initializing()
{
    InterlockedDecrement(&g_uModuleInitializing);
}

You can also use:

#if _MSC_VER >= 1300
while (InterlockedCompareExchange(&g_uModuleInitializing, 1, 0));
#else
while (InterlockedCompareExchange(((void **)&g_uModuleInitializing, 
(void*)1, (void *) 0));
#endif

_MSC_VER is defined as 1200 for VC6 and 1300 for VC7.

But this isn't necessarily reliable since it's OK to use VC6 (_MSC_VER == 
1200) with the VC7 header files (which are available separately as the 
platform SDK) - in fact I think this is what I did when testing this 
coding.

Cheers,

Tim
--
IBM Tivoli Access Manager Development
Gold Coast Development Lab, Australia
+61-7-5552-4001 phone
+61-7-5571-0420 fax



Adrian Dick <adrian.dick@uk.ibm.com> 
04/11/05 11:58 PM
Please respond to
"Apache AXIS C Developers List"


To
"Apache AXIS C Developers List" <axis-c-dev@ws.apache.org>
cc

Subject
RE: Possbile bug in Axis.cpp on Win32 (XP, VC7.1)






Rob,

As you comment below, the code in CVS does not exactly match the original
patch provided, due to the apparent differences in API between MS VC++
versions.

>From <MS VC++ 6.0 install>\Include\WINBASE.H
   PVOID
   WINAPI
   InterlockedCompareExchange (
       PVOID *Destination,
       PVOID Exchange,
       PVOID Comperand
       );

I initially tried using the version provided in the original patch (which
matches your suggested usage), but received compilation errors, basically
the reverse of those you are seeing.

Adrian
_______________________________________
Adrian Dick (adrian.dick@uk.ibm.com)

"Rob Lievaart" <Rob.Lievaart@nob.nl> wrote on 11/04/2005 14:22:45:

> Hi Adrian,
>
> There are two things here, one is the signature of the function,
> and one is the actual parameter values.
>
> I can imagine something about the different compiler versions
> being more or less picky about signatures which types can and cannot be
> converted to each other, but I find it hard to believe  that
> Microsoft changed the actual system call.  According to the
> documentation parameter 2 and 3 need to be the values to be
> compared and exchanged, but instead of these values, _pointers_
> to these values are passed.
>
> As far as I can see, the current function passes two pointers instead
> of a '1' and a '0' for exchange and comparand.  The result is that
> g_uModuleInitializing is never equal to the comparand, so it is never
> actually set to any other value then 0. The function will return the
> initial 0,  so it will continue thinking it has the lock, but without
> actually setting the flag.
>
> I guess, the chance of multiple threads actually trying to initialize at
>
> the same time, is pretty low, so it will seem to work, but it does not
> provide any protection this way.
>
> > This appears to be a problem between different versions of MS VC++.
> >
> > I applied this fix, as provided in
> > http://issues.apache.org/jira/browse/AXISCPP-557.
>
> Ehh, the patch you refer to in this issue shows the following code:
>
> + static void start_initializing()
> + {
> +     while (InterlockedCompareExchange(&g_uModuleInitializing, 1, 0));
> + }
>
> However the version in CVS has:
>
> static void start_initializing()
> {
>     long exchange  = 1;
>     long comperand = 0;
>     while (InterlockedCompareExchange(((void **)&g_uModuleInitializing),
> void*)&exchange, (void *) &comperand)));
> }
>
> Apart from the void * casts, the first one passes the values 1 and 0,
> and the
> second one passes the address of 2 variables that contain 1 and zero.
> The version in CVS definately does not match de documentation from
> Microsoft.
>
> I currently don't have VC6.0 installed to check out, what the problem
> is. But my
> guess is that the version in the original patch is correct.
> (I used the original version on VC7.1 and it compiles)
>
> Do you remember what problems VC6.0 had with the original version?
>
>
> Kind regards,
>
>
>
> Rob.
>
>
>



Mime
View raw message