| View previous topic :: View next topic |
| Author |
Message |
ribbs2521
Joined: 28 Sep 2007 Posts: 273 Location: New York
|
Posted: Wed Jan 06, 2010 7:45 pm Post subject: Question about CRITICAL |
|
|
I have a function which queries data from a MySQL database. If you try to run a second query without "closing" the first you will get a "command out of sync" error from MySQL. The "closing" occurrs at the end of the function so, since I'm getting these errors this tells me that this function is being run more than once at a time. I need to ensure that this function is never run more than once at any given time. I need to ensure that each time it is run, if finishes before it is run again. I put critical in the function but I still get the commands out of sync.
The problem, I believe, lies in that I have a sub routine which queries data every 60 seconds on a timer. There are also actions to various gui components that call queries so when a user clicks a gui action, if it happens to be at the same time the timed sub is running it causes this issue. I can't really post code because the code is over 80 pages. Honestly the code isn't what I'm initially concerned with, it's how I can stop a function from running parallel.
Am I misunderstanding Critical
Am I putting Critical in the wrong place
or is Critical not my solution and if so, what ideas do you have |
|
| Back to top |
|
 |
a_h_k
Joined: 02 Feb 2008 Posts: 627
|
Posted: Thu Jan 07, 2010 2:43 am Post subject: |
|
|
How about something like this...
| Code: | ;(within subroutine which queries data every 60 seconds on a timer)
While (InQuery = 1) {
} ; Wait for Query() to finish before calling again
Query()
;(user clicks a gui action)
While (InQuery = 1) {
} ; Wait for Query() to finish before calling again
Query()
Query()
{
global InQuery
InQuery = 1
(...)
InQuery = 0
} |
|
|
| Back to top |
|
 |
ribbs2521
Joined: 28 Sep 2007 Posts: 273 Location: New York
|
Posted: Thu Jan 07, 2010 12:41 pm Post subject: |
|
|
| I didn't think of that I'll give it a shot, should work, thanks a ton. |
|
| Back to top |
|
 |
ribbs2521
Joined: 28 Sep 2007 Posts: 273 Location: New York
|
Posted: Thu Jan 07, 2010 9:08 pm Post subject: |
|
|
OK, so, some wierd stuff happens here, I'll try to explain.
Basically, if I leave the While loop empty, it never completes the first call to that function. Here is what happens
10 seconds....
gonna run and inQuery is ><
Query In Process (From the Timed Call)
Ran Timed Routine
wait 1 second
I press F4
Query In Process (From the F4 call)
....wait for timed routine to run again....
gonna run and inQuery is >1<
wait 1 second
Click OK
then nothing happens... when I opened the debugger it shows it looping in the timed routine's while loop.
Here is the code
| Code: | SetTimer, TimedRoutine, 10000
F4::
While (inQuery) {
}
querytest()
msgbox, inQuery is >%inQuery%<
return
TimedRoutine:
msgbox, gonna run and inQuery is >%inQuery%<
While (inQuery) {
}
querytest()
msgbox, Ran Timed Routine
return
querytest()
{
global inQuery
inQuery := 1
Msgbox, Query In Process
inQuery := 0
} |
The wierdest part is that if I put return in the while loop everything works fine, as soon as I click OK from the F4 call, the timed subroutine starts going again. I originally had the while loop in the beginning of the function but took it out in case that was the reason but got the same results.
That's the code I used just to test that method so you can test it too if you want. |
|
| Back to top |
|
 |
ribbs2521
Joined: 28 Sep 2007 Posts: 273 Location: New York
|
Posted: Fri Jan 08, 2010 1:14 pm Post subject: |
|
|
I think it's because It's looking at different memory addresses. If AHK is like other languages then each time you change the value or size of the variable the address is going to change. So, I think it may be looping waiting for the wrong memory address to change and it's not so it's stuck in a continuous loop.
I'm not sure it's possible but maybe that's what is going on, that's the only thing I can think of at this point. |
|
| Back to top |
|
 |
Kellianjaxon
Joined: 04 Jan 2008 Posts: 102
|
Posted: Sat Jan 09, 2010 1:39 am Post subject: |
|
|
| No, actually the problem has to do with thread priorities. Because TimedRoutine thread interrupts F4 hotkey thread and they have equal priorities, the hotkey thread never gets to carry on execution until TimedRoutine finishes (which it doesn't do in the code example). |
|
| Back to top |
|
 |
a_h_k
Joined: 02 Feb 2008 Posts: 627
|
Posted: Sun Jan 10, 2010 4:51 am Post subject: |
|
|
Here you go... (tested)
| Code: | SetTimer, TimedRoutine, 10000
queueNum = 0
Loop
{
tooltip %inQuery% ----- %queueNum%: %queue1% - %queue2% - %queue3% - %queue4%
While (inQuery) { ;Wait till inQuery() not running
Sleep, 10 ;So don't hog cpu
}
While (!queueNum) { ;Wait for queue to have item/s
Sleep, 10
}
If (queue1 = "F4")
{
querytest() ;Have main "F4" code here now
msgbox,,, Ran F4, 1
}
Else If (queue1 = "TR")
{
querytest() ;Have main "TimedRoutine" code here now
msgbox,,, Ran TimedRoutine, 1
}
}
F4:: ;Quick IN/OUT routine now (to avoid priority/interruption issues)
queueNum++
queue%queueNum% = F4
tooltip %inQuery% ----- %queueNum%: %queue1% - %queue2% - %queue3% - %queue4%
return
TimedRoutine: ;Quick...
queueNum++
queue%queueNum% = TR
tooltip %inQuery% ----- %queueNum%: %queue1% - %queue2% - %queue3% - %queue4%
return
querytest()
{
global
inQuery := 1
tooltip %inQuery% ----- %queueNum%: %queue1% - %queue2% - %queue3% - %queue4%
Msgbox, Query In Process
RemoveFirst()
inQuery := 0
tooltip %inQuery% ----- %queueNum%: %queue1% - %queue2% - %queue3% - %queue4%
}
RemoveFirst()
{
Global
Loop, %queueNum% ;Shift queue items left by 1 (FIFO; #1 = top of queue)
{
next := A_Index + 1
queue%A_Index% := queue%next%
}
queueNum--
}
|
|
|
| Back to top |
|
 |
|