What’s the best way to do passing records of a queue to other queue in another thread?
I have a background monitoring window that will take care of all the data processing to produce outputs that is needed from my dashboard window so that it will not block the dashboard user inputs.
I use notify() and notification() to pass simple data output such as total item record, etc. that only needs single value. but have no idea how to pass record from background monitoring queue to my dashboard queue. Otherwise I really need to define that queue globally
If you have stringtheory and Jfiles, you could use a couple of quick statement to convert the queue to json text and pass it as a simple string, reverse the procedure to load.
I think it’s something simple like json.save(Queue) to save and json.load to load. But docs would be a good idea
Also check the serialize methods in StringTheory, particularly SerializeQueue which basically iterates SerializeGroup over each queue entry. Default is CSV format but you can override the boundaries/separators if desired.
Or did you mean passing the queue using some pointer? Obviously you would need a global queue type and a critical section so that only one thread could access it at a time. Thinking about it if you were going down that route you may as well just have the whole queue global and synchronise access. You might be better using the inmemory driver? Or perhaps Capesoft’s MaxQueue.
You can pass arbitrarily complex structures between threads
The general concept is
In the calling Thread:
NEW memory in the calling thread
copy the data into the NEW’d structure
pass the ADDRESS (or INSTANCE) to the receiving thread
In the receiving thread:
interpret the address as a reference to the expected structure
use the complex structure
DISPOSE the reference
Note: ADDRESS(Queue) points the queue buffer, whereas INSTANCE( Queue, THREAD() ) points to the entire queue
Calling thread:
CODE
ToPassQ &= NEW QueueTypeYada
DO FillPassQ_FromActualData
NOTIFY( Notify:QueueTypeYada, ReceivingThread, INSTANCE( ToPassQ, THREAD() ) )
Receiving Thread:
INCLUDE('QueueTypeYada.inc'),ONCE
ThisWindow CLASS(WindowManager)
YadaQ &QueueTypeYada
TakeNotify PROCEDURE()
TakeNotify:QueueTypeYada PROCEDURE( SIGNED xThread, LONG xParam)
YadaQ:Dispose PROCEDURE()
YadaQ:Free PROCEDURE
TakeEvent PROCEDURE,DERIVED,BYTE,PROC
Kill PROCEDURE,PROC,BYTE,DERIVED ! Level:Notify means dead already
END
CODE
!....
ThisWindow.TakeEvent PROCEDURE()
CODE
CASE EVENT()
OF EVENT:NOTIFY; SELF.TakeNotifiy()
END
RETURN Parent.TakeEvent()
ThisWindow.TakeNotifiy PROCEDURE()
NotifyCode UNSIGNED
NotifyThread SIGNED
NotifyParameter LONG
CODE
IF NOTIFICATION(NotifyCode,NotifyThread,NotifyParameter)
CASE NotifyCode
OF Notify:QueueTypeYada; SELF.YadaQ:Dispose()
ThisWindow.YadaQ &= 0 + NotifyParameter
! handle other notifications here
END
END
YadaQ:Dispose PROCEDURE()
CODE
IF NOT ThisWindow.YadaQ &= NULL
SELF.YadaQ:Free() ! knows about nested references and handles them too
DISPOSE( ThisWindow.YadaQ )
END
ThisWindow.Kill PROCEUDRE()
CODE
SELF.YadaQ:Dispose()
PARENT.Kill()
Note: I (nearly?) always wrap my queues in a class dervied from my ctQueue
which simplifies the copying, freeing and disposing among other things
Also I use a derived window manager which has a .TakeNotifiy already added
If you just want to pass One Queue record that can be put in a STRING. Both threads need to know the QUEUE Declaration. The easy way is to define a TYPE then inherit that.
QRecStrRef &STRING
...
!Send Record to another thread
GET(SomeQ,X)
QRecStrRef &= NEW( STRING( SIZE(SomeQ) ))
QRecStrRef = SomeQ !Q record in string
NOTIFY( Xxxxx, TargetThreadNo, ADDRESS(QRecStrRef) )
!Do the DISPOSE(QRecStrRef) in Target amd NOT here
In the Target Thread turn that address into a STRING and put that in a local Queue or Group with the same structure.
QRecStrRef &STRING
QRecStrAddr LONG
...
NOTIFICATION( NCode, FromThreadNo, QRecStrAddr)
IF NCode=Xxxxx AND QRecStrAddr <> 0 THEN
QRecStrRef &= (QRecStrAddr) !Now we have a STRING
Local_SomeQ = QRecStrRef
! Now you have a Queue or Group here
DISPOSE(QRecStrRef) !Else Leak
END
I think this is what I needed, I will try this and let you guys know, btw both my procedure threads are in different dll’s so I will try if this works. Thanks.