From: Alf P. Steinbach on
* David Given:
> By default Windows handles sizing and moving using a modal event loop.
> That is, when the user presses the mouse button on the window border, a
> separate event loop is started up that handles the sizing or moving.
> It's only when the user releases the button that the application's own
> event loop is returned to.
>
> Unfortunately the app I'm porting has to have control over its event
> loop. Unless flow of execution goes through the event loop, it doesn't
> do stuff like redraw. Which means that right now, the app doesn't redraw
> while being resized.
>
> It would actually be easier for me to write my own window resize code
> than it is to rearrange the app. So, before I do this --- is there any
> way to persuade Windows *not* to use a modal sizing event loop, and
> instead to use the application's normal event loop instead?
>
> This is all with low-level GDI and Win32 calls --- no frameworks.

Perhaps you can just let the application output to a control filling out the
main window's client area. Then it can run on its own thread.

Cheers & hth.,

- Alf
From: David Schwartz on
On Feb 3, 3:20 pm, David Given <d...(a)cowlark.com> wrote:

> I don't suppose there's any easy way of doing synchronous RPC between
> two event loops, is there?

There are a lot of ways to do it, all of which are pretty simple. I
would suggest not using actual RPC though, as it's overkill for
threads.

Define a structure to hold a message (or pointer to one) and reply (or
pointer to one). The thread that creates the message owns it until it
hands it off to the other thread. The other thread owns the reply
until it hands it off to the other thread. Put the messages and
replies on synchronous queues.

So when you get a windows message, it's:

1) Lock the message queue.
2) Put the new message on the queue.
3) Unlock the message queue.
4) Signal the other thread (through an event).
5) Block on the reply queue.
6) Lock the reply queue
7) Get the reply
8) Unlock the reply queue

If you only are going to have one event in flight at a time, you don't
need a queue. It can just be a single pointer to a pointer.

DS
From: David Given on
On 04/02/10 12:04, David Schwartz wrote:
[...]
> 1) Lock the message queue.
> 2) Put the new message on the queue.
> 3) Unlock the message queue.
> 4) Signal the other thread (through an event).
> 5) Block on the reply queue.
> 6) Lock the reply queue
> 7) Get the reply
> 8) Unlock the reply queue

Aaargh. (I've done this stuff before on other platforms. It works, it's
not even terribly hard, but it's *never* pretty...)

I think I can simplify this, given my requirements; I only want one
message in flight at a time, so I think I can achieve everything with a
single semaphore and the user parameters of a WM_USER event: the UI
thread receives an event, packages it in a structure on the stack, sends
WM_USER to app thread, blocks on semaphore; app thread receives event,
unpacks structure, does whatever it needs to do, writes return value
into structure, releases sempahore; UI thread pulls return value out of
structure and returns to the Windows event loop.

Incidentally, you may be interested to know that the Unix version of my
app is 6000 lines of code (plus libraries). My current Windows version
(which is finished, except for resize support) is 8500 lines.

(Or... hmm. The UI and app threads will never run concurrently. This
means I may be able to simplify things even more using fibres; that will
let me disconnect the app and UI stacks without needing all the overhead
of having to have seperate threads and event queues.)

Anyway, thank-you. You've given me a number of very useful ideas; I
should be able to make this work.

--
┌─── dg@cowlark.com ───── http://www.cowlark.com ─────

│ life←{ ↑1 ⍵∨.^3 4=+/,¯1 0 1∘.⊖¯1 0 1∘.⌽⊂⍵ }
│ --- Conway's Game Of Life, in one line of APL
From: Kerem Gümrükcü on
Hi,

> (Or... hmm. The UI and app threads will never run concurrently. This
> means I may be able to simplify things even more using fibres; that will
> let me disconnect the app and UI stacks without needing all the overhead
> of having to have seperate threads and event queues.)

never rely on such a assumption! You should use some kind of
synchronization like kernel primitives for tasks that possibly could
clash, since windows is not really thread safe when it comes to
concurrent UI threads and object access.

Regards

Kerem

--
-----------------------
Beste Grüsse / Best regards / Votre bien devoue
Kerem Gümrükcü
Latest Project: http://www.pro-it-education.de/software/deviceremover
Latest Open-Source Projects: http://entwicklung.junetz.de
-----------------------

From: David Given on
On 05/02/10 02:26, Kerem Gümrükcü wrote:
[...]
> never rely on such a assumption! You should use some kind of
> synchronization like kernel primitives for tasks that possibly could
> clash, since windows is not really thread safe when it comes to
> concurrent UI threads and object access.

Ah, but because fibres run from within a single thread there is no
concurrency and therefore no problem! That's the beauty of coroutines
--- they allow you to decouple flow of execution from the stack,
allowing you to have multiple stacks between which you shift as you
desire. As it's all synchronous and explicit all the concurrency
problems of threads just vanish.

(This is, in fact, *exactly* the sort of problem that coroutines are
for, and I wish I'd thought of them earlier. I was only reminded that
Windows has decent coroutine support when I saw the section on fibres
while reading up on the threading APIs...)

In fact, it's all working beautifully now; the application has its own
event loop in one fibre, and Windows has *its* own event loop in another
fibre, and I simply pass control from one to the other whenever I need
to send an (application) event. Very elegant and surprisingly easy.

--
┌─── dg@cowlark.com ───── http://www.cowlark.com ─────

│ life←{ ↑1 ⍵∨.^3 4=+/,¯1 0 1∘.⊖¯1 0 1∘.⌽⊂⍵ }
│ --- Conway's Game Of Life, in one line of APL