At 12:21 AM 12/29/2002, [EMAIL PROTECTED] wrote:
>On 29 Dec 2002 [EMAIL PROTECTED] wrote:
>
>> wrowe 2002/12/28 21:44:02
>>
>> First; once any apr object is closed, the results are undefined.
>...
>> Index: testdso.c
>> --- testdso.c 19 Dec 2002 16:15:29 -0000 1.30
>> +++ testdso.c 29 Dec 2002 05:44:01 -0000 1.31
>> ...
>> @@ -155,17 +155,11 @@
>>
>> status = apr_dso_unload(h);
>> CuAssert(tc, apr_dso_error(h, errstr, 256), APR_SUCCESS == status);
>> -
>> - status = apr_dso_sym(&func1, h, "print_hello");
>> - CuAssertIntEquals(tc, APR_EINIT, status);
>> }
>
>I seriously disagree with this change.
>If the dso is unloaded, you
>shouldn't be able to find a symbol in it anymore.
I agree with you. However, h is now undefined. This means that we
will generally react by segfaulting or throwing any indeterminate error.
EINIT is a Unixism.
>One of the points of
>APR is that it removes this kind of platform difference. Right now,
>somebody can program on Windows, and use the wrong pool to load a library.
>Then, after the pool is cleared still be able to dso_sym that library.
Why do you suppose they can do that? Win32 returns an error, just
not that specific error. The test failed because the result was not
EINIT. Once a file/dso/shm/pipe/socket etc is closed/unloaded, that's
it, game over. How a platform expresses the error is undefined.
>However, if that program is then brought to another platform, it will no
>longer work.
It doesn't work today once the symbol is unloaded.
>I am currently -0.9 for this change. Is there a reason we can't solve
>this problem so that incorrect pool scope can be easily found on all
>platforms?
That's a bogus arguement. If h is within a more-limited pool scope
than the programmer intended, then the next apr_dso_sym() *will*
segfault, and not return some gracious EINIT.
Win32 invalidates the object handle within the apr_dso_t (as it does
for many other objects.) Double-closing is protected by the pre-test
for an invalid handle.
If you want to define the behavior of all functions following closure or
unloading, then you must go through all platforms and introduce tests
for a valid handle on all operations. I really think that is overkill and
undermines the original design constraints.
However, as I suggested when we first argued the issue of argument
checking, it isn't unreasonable to have small sections such as...
APR_DECLARE(apr_status_t) apr_foo_fn(apr_foo_t *t)
{
#ifdef DEBUG_ARGS
if (!t)
return APR_EINVAL;
if (!t->ptrmbr)
return APR_EINIT;
#endif
[code body]
}
etc.
It's all in the distinction between *defined* behavior, which can be tested,
and *undefined* behavior which is untestable. {Unless we can test sevg
as a success case, perhaps using STL exceptions.}
Bill