Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

WinInitialize in rexx dll - why?

3 views
Skip to first unread message

Michael Greene

unread,
Jan 14, 2008, 9:17:12 PM1/14/08
to
I was looking through the SysIni function in the sample provided in the
OS/2 toolkit and I see the following:


BOOL terminate = TRUE; /* perform WinTerminate call */

... code ...


hab = WinInitialize((USHORT)0); /* create anchor block */

if (!hab) { /* already done? get desktop anchor */
hab = WinQueryAnchorBlock(HWND_DESKTOP);

terminate = FALSE; /* don't terminate */
}


... code ...

if (terminate) WinTerminate(hab); /* destroy anchor block */

and before exit points:

if (terminate) WinTerminate(hab);


I don't understand why this is needed or better put, I don't see in in
the docs where this is required. Am I missing something?

Mike

Rich Walsh

unread,
Jan 15, 2008, 1:46:03 AM1/15/08
to

Before calling any PM functions, you need to initialize PM for that thread.
Of course, if you allocate resources you should free them when you're done.
However, it's possible that some other code already did the init, in which
case you certainly shouldn't free stuff that other code may still need.

This code is designed to ensure that WinInitialize() has been called and
to determine whether it should call WinTerminate() or leave that task to
some other code.

If WinInitialize() hasn't been called previously, it will return a HAB.
The non-zero return signals that this code should call WinTerminate().
If it has been called previously, the second call will generate an error
and return zero, signaling that this code shouldn't call WinTerminate().
Since the code needs a HAB to pass to subsequent calls, it retrieves the
current HAB by calling WinQueryAnchorBlock().

Note: this code appears to ignore one possibility: that it's operating
in a non-PM environment where WinInitialize() and WinQueryAnchorBlock()
will always fail. It may be that the author chose to ignore that here
and instead deals with it when a subsequent Prf* call fails (if PM isn't
present, ini-access functions will also always fail).

--
== == almost usable email address: Rich AT E-vertise.Com == ==
___________________________________________________________________
|
| New! DragText v3.9 with NLS support
Rich Walsh | A Distinctly Different Desktop Enhancement
Ft Myers, FL | http://e-vertise.com/dragtext/
___________________________________________________________________

Paul Ratcliffe

unread,
Jan 15, 2008, 4:56:00 AM1/15/08
to
On Mon, 14 Jan 2008 21:17:12 -0500, Michael Greene <list...@cox.net> wrote:

> I don't understand why this is needed or better put, I don't see in in
> the docs where this is required. Am I missing something?

DLLs operate in the context of the calling process. Whatever the DLL
allocates it should free. It should not (read MUST NOT) free things it didn't
allocate, even it it uses them. A lot of people forget this very basic premise.

Alex Taylor

unread,
Jan 15, 2008, 6:39:02 AM1/15/08
to
On Tue, 15 Jan 2008 06:46:03 UTC, "Rich Walsh" <spamyo...@127.0.0.1> wrote:

> Of course, if you allocate resources you should free them when you're
> done. However, it's possible that some other code already did the init,
> in which case you certainly shouldn't free stuff that other code may still
> need.
>
> This code is designed to ensure that WinInitialize() has been called and
> to determine whether it should call WinTerminate() or leave that task to
> some other code.

I see I neglected that particular bit of logic in RXULS, although I did put
such a check in for the subsequent WinCreateMsgQueue() call. Fixed.


--
Alex Taylor
Fukushima, Japan
http://www.cs-club.org/~alex

Please take off hat when replying.

Ilya Zakharevich

unread,
Jan 15, 2008, 6:42:38 PM1/15/08
to
[A complimentary Cc of this posting was NOT [per weedlist] sent to
Paul Ratcliffe
<ab...@orac.clara.co.uk>], who wrote in article <slrnfop0pg...@news.pr.network>:

> > I don't understand why this is needed or better put, I don't see in in
> > the docs where this is required. Am I missing something?

> DLLs operate in the context of the calling process. Whatever the DLL
> allocates it should free. It should not (read MUST NOT) free things it didn't
> allocate, even it it uses them. A lot of people forget this very basic premise.

Sure, if you want to write buggy code, feel free to code this way...

A "more correct" way is: if you need a resource, you need a
thread-safe use counter. Chronologically-first one who needs a
resource, allocates it. Chronologically-last one who ceases to need a
resource, deallocates it.

=======================================================

But given that REXX DLLs work un absolutely undefined environment
(which resources are shared for different processes, and which are
not?), I'm not sure that even this is bullet-proof. I would not be
comfortable with freeing ANYTHING from REXX DLL; I was bitten by
another process unloading DLLs from under my nose too many times...

A conservative approach is to let users choose what he thinks is safer
in their environment: to leak resources, or to risk out-of-order
freeing of the resources.

=======================================================

So, IMO, the original code does not make too much sense. Too little,
too late...

Hope this helps,
Ilya

0 new messages