Global Queues: More than one routine accessing 
Author Message
 Global Queues: More than one routine accessing

Is there a way to allow two or more processes access global memory queues
simultaneously?  Does the queue record buffer get trashed by one while
another is using it?

I have a queue that is being fed by one routine, then read and records
discarded by another.  Does adding to the queue while the read is in
progress, or deleting a record while the other routine is adding a record
cause a conflict?  If so, what is the best way to avoid this?

Secondly, is it possible to have a queue of pointers to other queues, then
reference the real queue and its fields via the pointer?  If two references
point to the same queue, is the record buffer shared?

Thanks!

Rob
--
Robert S. Mikkelsen
Precision Computing, Inc
Valrico (Tampa), Florida, USA



Wed, 15 Aug 2001 03:00:00 GMT  
 Global Queues: More than one routine accessing

Quote:

> Is there a way to allow two or more processes access global memory queues
> simultaneously?  Does the queue record buffer get trashed by one while
> another is using it?

> I have a queue that is being fed by one routine, then read and records
> discarded by another.  Does adding to the queue while the read is in
> progress, or deleting a record while the other routine is adding a record
> cause a conflict?  If so, what is the best way to avoid this?

> Secondly, is it possible to have a queue of pointers to other queues, then
> reference the real queue and its fields via the pointer?  If two references
> point to the same queue, is the record buffer shared?

That's a question and a half!<g>
In CW at present, I dont believe there is any danger as one process must
finish and give up control before the other can start unless you have some
non-CW process that calls CW and does something on a random basis.  An
example would be a Comm program requires a CW call back procedure. The
callback procedure can be called at anytime.  If that callback procedure
accessed a global variable while the comm program using the callback had its
time slice there is potential problem.  To resolve that, there is an api
construct called critical sections that can be used to prevent two threads
from interupting each other when sharing a global variable.  If CW ever
becomes truely multi-threaded this is a new headache (I mean that literally)
we will then face as does every other windows programmer.

Yes Queues can contain references to other queues.

ParentQ queue
Id long
childQ &ChildQType
  end
  code
  clear(parentQ)
  ParentQ.Id=1
  ParentQ.ChildQ &= New(ChildQType)
  Add(ParentQ)

  Later must remember to dispose() of any thing you new().
  This is very easy in OOPS.

---
Jim Kane  - TeamTopSpeed
Productive Software Solutions
Can't Find that Message?
Get Organized, Get ForKeeps!
www.fkeeps.com



Wed, 15 Aug 2001 03:00:00 GMT  
 Global Queues: More than one routine accessing
Thanks for the insight, Jim.  I am, unfortunately, using a callback for the
DDE functions that I wrote using Windows API calls.  Unfortunately, CW does
not support Item referencing, only Service and Topic, and the app that I was
interfacing with wanted items identified as well.  This means that the
callback can (and does) occur when CW is writing to the queue structure.
Even worse, I have a routine that saves the queue to disk and  clears it
when the queue becomes too large.  If the callback function is operating at
that time I get a GPF.  This is not a good thing...

Please tell me more about the critical sections API call as either that, or
setting a flag whenever the queue is being manipulated, appears to be the
only way to get around this problem.

Regarding reference variables - would two variables that reference the same
queue share the same record buffer?  I think that they would, but I am
hoping that they would not.  If they do, is there a workaround?

Thanks again!

Rob

Quote:

>In CW at present, I dont believe there is any danger as one process must
>finish and give up control before the other can start unless you have some
>non-CW process that calls CW and does something on a random basis.  An
>example would be a Comm program requires a CW call back procedure. The
>callback procedure can be called at anytime.  If that callback procedure
>accessed a global variable while the comm program using the callback had
its
>time slice there is potential problem.  To resolve that, there is an api
>construct called critical sections that can be used to prevent two threads
>from interupting each other when sharing a global variable.



Wed, 15 Aug 2001 03:00:00 GMT  
 Global Queues: More than one routine accessing
Quote:

> Please tell me more about the critical sections API call as either that, or
> setting a flag whenever the queue is being manipulated, appears to be the
> only way to get around this problem.

> Regarding reference variables - would two variables that reference the same
> queue share the same record buffer?  I think that they would, but I am
> hoping that they would not.  If they do, is there a workaround?

Yes they do. Ref variable is little more than a pointer. Hope there arent any
workarrounds.

A general discussion of threading is a topic for books. It suffices to say
there are mutex, semaphores, events, critialsections all with different
possible reset and other properties. You need a book like the one by Richter,
Advanced Windows, that discusses sync objects to really pick what is best.  
Partly preference. I know the CW developers Richard Chapman uses a lot of
Semaphores and I rarely do.  In any case, here's the 5 cent tour of critical
sections:
Global Data:
CRITICAL_SECTION    GROUP
DebugInfo                ULONG
LockCount                LONG
RecursionCount           LONG
LockSemaphore            Unsigned
Reserved                 ULONG
                        END
YourGloQ Queue
field1 long
  end
InitQ Procedure
  code
    InitializeCriticalSection(Address(Critical_Section))
KillQ Procedure
  code
    DeleteCriticalSection(Address(Criticial_Section))

AddQ Procedure(long field1)
  code
  EnterCritialSection(Address(Criticial_Section))
  !If someone here before you it hangs until other person leaves,
  !Makes CritSect a RED light
  YourGloQ.Field1 = Field1
  Add(YourGloQ)
  LeaveCriticalSection(Address(Critical_Section))
  !make Crit section a Green light
delQ procedure(long ptr)
  code
  EnterCritialSection(Address(Criticial_Section))
  Get(YourGloQ.Field1, Ptr)
  Delete(YourGloQ)
  LeaveCriticalSection(Address(Critical_Section))

  Notice get and delete in one block.
  Remember Critical_section is global so two processes cant add and delete at
the same time.
  Its best done with OOPS or put code in a separate memeber module.
  Never, never, never access the Q outside a enter/leave pair.
  Never, never, never assume the Q position will stay the same between too
calls. Soon as you leave the critical section, it could change.
  Best to new() the Q in the init and dispose() the Q in the kill.
  Usually I use a group Like() my Q and set it up in local memory then pass
the group as a parameter to the 'guarded functions' and do a memcpy into the
real Q buffer but that's not a requirement just makes life easy.

  Now for the bad news.  This still may not be safe.  When you call
Add(YourGloQ) and the addQ procedure above is called by the callback, other
code in your app may be calling the add(Queue) library code in the CW
Library. Since the CW Queue Library is not thread safe, things still may get
mashed. The only totally safe method is to allocate a block of memory
(globalalloc()) within your class and create your own Q like arrangement
managing your own pointers. The critical sections can only protect what is
inside the enter/leave pair.  Since the library code is outside that, your
not safe.

---
Jim Kane  - TeamTopSpeed
Productive Software Solutions
Can't Find that Message?
Get Organized, Get ForKeeps!
www.fkeeps.com



Wed, 15 Aug 2001 03:00:00 GMT  
 Global Queues: More than one routine accessing
Thanks for the input, Jim.  I will look into it further.  In the meanwhile I
will try a semaphore and check if that does it for me.  Thanks for taking
the time to get me moving in the right direction!

The safest bet that I can see is checking to see if a flag is cleared,
BORing it with the a unique bit for the section that you are in, then
looping back to see if you are the only one in the section.  If not, clear
the flag, wait a predetermined count (different rates for each section),
then try it again.  Otherwise, there is the VERY slim possibility that both
procedures hit the flag at exactly the same time.  Of course, the traffic
through the callback is not that heavy.

I will have to play with a couple ideas and see what works best.

Rob

Quote:

>  Now for the bad news.  This still may not be safe.  When you call
>Add(YourGloQ) and the addQ procedure above is called by the callback, other
>code in your app may be calling the add(Queue) library code in the CW
>Library. Since the CW Queue Library is not thread safe, things still may
get
>mashed. The only totally safe method is to allocate a block of memory
>(globalalloc()) within your class and create your own Q like arrangement
>managing your own pointers. The critical sections can only protect what is
>inside the enter/leave pair.  Since the library code is outside that, your
>not safe.



Wed, 15 Aug 2001 03:00:00 GMT  
 Global Queues: More than one routine accessing
Or use file-io on a ram-disk,
as was suggested in another thread.
--
Dr.Ruud

Chaos rules

Quote:



>> Please tell me more about the critical sections API call as either
that, or
>> setting a flag whenever the queue is being manipulated, appears to
be the
>> only way to get around this problem.

>> Regarding reference variables - would two variables that reference
the same
>> queue share the same record buffer?  I think that they would, but I
am
>> hoping that they would not.  If they do, is there a workaround?

>Yes they do. Ref variable is little more than a pointer. Hope there
arent any
>workarrounds.

>A general discussion of threading is a topic for books. It suffices
to say
>there are mutex, semaphores, events, critialsections all with
different
>possible reset and other properties. You need a book like the one by
Richter,
>Advanced Windows, that discusses sync objects to really pick what is

best.


Thu, 16 Aug 2001 03:00:00 GMT  
 Global Queues: More than one routine accessing
Quote:

> Or use file-io on a ram-disk,
> as was suggested in another thread.
> -

Would not help unless CW fileIO library code was thread safe.  It isnt.
---
Jim Kane  - TeamTopSpeed
Productive Software Solutions
Can't Find that Message?
Get Organized, Get ForKeeps!
www.fkeeps.com


Thu, 16 Aug 2001 03:00:00 GMT  
 Global Queues: More than one routine accessing
Quote:

> The safest bet that I can see is checking to see if a flag is cleared,

Trying to duplicate a critical section with a global is the hard way.
At the root of the problem is if any other code in your program is
calling any other Queue related function while your callback calls a
Queue related function you'll still have trouble potentially.
---
Jim Kane  - TeamTopSpeed
Productive Software Solutions
Can't Find that Message?
Get Organized, Get ForKeeps!
www.fkeeps.com


Thu, 16 Aug 2001 03:00:00 GMT  
 Global Queues: More than one routine accessing
Quote:

> Isn't that very unusual?
> Please show a simple example that goes wrong.

I have no idea what goes on inside the CW runtime library. However I
have confirmed with Richard Chapman the head of the development center
that the library is not api thread safe including file IO, Queues,
Strings. If different api threads call the library anything can happen
as this person found out with Queues.
---
Jim Kane  - TeamTopSpeed
Productive Software Solutions
Can't Find that Message?
Get Organized, Get ForKeeps!
www.fkeeps.com


Thu, 16 Aug 2001 03:00:00 GMT  
 Global Queues: More than one routine accessing

Quote:
>> Or use file-io on a ram-disk,
>> as was suggested in another thread.
>Would not help unless CW fileIO library code was thread safe.  It

isnt.

Isn't that very unusual?
Please show a simple example that goes wrong.
--
Dr.Ruud

Chaos rules



Fri, 17 Aug 2001 03:00:00 GMT  
 
 [ 10 post ] 

 Relevant Pages 

1. One routine-global variables, no globals lots of routines

2. Accessing one's main script's global from imported libraries

3. How do you make a global queue BINDABLE?

4. CLASSes and QUEUEs (was: Re: QUEUE in QUEUE)

5. queue management pli routines

6. Any one using Dan Friedman's EIP on Queue Templates - Help

7. Non-Procedure routine's variables not global ?

8. Transfer global data from one application to another?

9. Share Global Variables data between two separate programs in one machine

10. fortran question [how does one set global variables?]

11. embedded Python: one thread hangs while trying to get global Python lock

12. REXX access to AS/400 data queues

 

 
Powered by phpBB® Forum Software