[VW 7.5] Interrupting HostPrinter>>primCreatePrintJobNamed:

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|

[VW 7.5] Interrupting HostPrinter>>primCreatePrintJobNamed:

Stew MacLean

Hi,

 

I’m finding that

 

HostPrinter>>primCreatePrintJobNamed: aString

            <primitive: 1210>

            ^self primitiveFailed

 

is disappearing down a “black hole” for 30 seconds before the primitive fails.

 

This occurs when the computer that has the printer is switched off, and possibly with other scenarios as well.

 

I’ve tried to time the call out by using:

 

BlockClosure>> valueWithinMilliseconds: anInteger orDo: anotherBlock

 

            "Evaluate the receiver and answer the result, giving the reciever at most anInteger milliseconds to complete.

            After that, terminate execution and answer the result of anotherBlock instead."

 

            | thisProcess timer result |

 

            thisProcess := Processor activeProcess.

            timer :=

                        [(Delay forMilliseconds: anInteger) wait.

                        thisProcess interruptWith: [Tools.Trippy.TimeoutExceeded raise]]

                                    forkAt: thisProcess priority + 1.

            [[result := self value] ensure: [timer terminate]]

                        on: Tools.Trippy.TimeoutExceeded

                        do: [:ex | result := anotherBlock value].

 

            ^result

 

but the Delay waits till primCreatePrintJobNamed: returns before proceeding.

 

I’m assuming that the Delay timing is somehow being stopped by the blocking HostPrinter>>primCreatePrintJobNamed: aString call.

 

In this case, I’m making the call just to get the dimensions of the print medium, but not actually using the printer. So I would like to use the printer dimensions if one is available, otherwise use defaults if the call times out.

 

I’ve considered using a TimedPromise, but as it uses Delay’s I figure it will have the same problem.

 

So I’m wondering if there is a way of timing this call out?

 

Thanks,

 

Stewart

 

 

 

Reply | Threaded
Open this post in threaded view
|

Re: [VW 7.5] Interrupting HostPrinter>>primCreatePrintJobNamed:

Reinout Heeck

You cannot interrupt primitives.

I guess you will need to re-implement the primitive in a way that  
supports either timeout or interrupting (using DLLCC and perhaps the  
threaded API).

How many operating systems do you need to support?


R
-

Reply | Threaded
Open this post in threaded view
|

Re: [VW 7.5] Interrupting HostPrinter>>primCreatePrintJobNamed:

Eliot Miranda-2


On 9/29/07, Reinout Heeck <[hidden email]> wrote:

You cannot interrupt primitives.


Not quite true.  Try interrupting

    | a |
    a := Array with: #perform:withArguments: with: nil.
    a at: 2 put: a.
    a perform: a first withArguments: a

:) :)

There are a handful of potentially long-running primitives that can be interrupted, e.g. the incremental GC primitive.  But the Windows printing primitives are not amongst them.  The issue there is that the Win32 API cals are difficult to interrupt.  The VM would have to spawn another thread ad execute the Win32 API call on that thread.

I guess you will need to re-implement the primitive in a way that
supports either timeout or interrupting (using DLLCC and perhaps the
threaded API).


Right.  Which is how it should have been done in the first place.

How many operating systems do you need to support?


R
-


Reply | Threaded
Open this post in threaded view
|

RE: [VW 7.5] Interrupting HostPrinter>>primCreatePrintJobNamed:

Steven Kelly
In reply to this post by Stew MacLean
Message
You might be able to use a threaded printer call to see whether the printer is available or not. You can make that time out after a second or two, and if you haven't had an answer you know not to call the primitive. IIRC, Windows Goodies in the public store has the threaded printer calls for Windows. You probably won't need them for other platforms, since I don't imagine another platform would be as dumb as Windows :-).
 
Steve
-----Original Message-----
From: Stewart MacLean [mailto:[hidden email]]
Sent: 29. syyskuuta 2007 4:56
To: [hidden email]
Subject: [VW 7.5] Interrupting HostPrinter>>primCreatePrintJobNamed:

Hi,

 

I’m finding that

 

HostPrinter>>primCreatePrintJobNamed: aString

            <primitive: 1210>

            ^self primitiveFailed

 

is disappearing down a “black hole” for 30 seconds before the primitive fails.

 

This occurs when the computer that has the printer is switched off, and possibly with other scenarios as well.

 

I’ve tried to time the call out by using:

 

BlockClosure>> valueWithinMilliseconds: anInteger orDo: anotherBlock

 

            "Evaluate the receiver and answer the result, giving the reciever at most anInteger milliseconds to complete.

            After that, terminate execution and answer the result of anotherBlock instead."

 

            | thisProcess timer result |

 

            thisProcess := Processor activeProcess.

            timer :=

                        [(Delay forMilliseconds: anInteger) wait.

                        thisProcess interruptWith: [Tools.Trippy.TimeoutExceeded raise]]

                                    forkAt: thisProcess priority + 1.

            [[result := self value] ensure: [timer terminate]]

                        on: Tools.Trippy.TimeoutExceeded

                        do: [:ex | result := anotherBlock value].

 

            ^result

 

but the Delay waits till primCreatePrintJobNamed: returns before proceeding.

 

I’m assuming that the Delay timing is somehow being stopped by the blocking HostPrinter>>primCreatePrintJobNamed: aString call.

 

In this case, I’m making the call just to get the dimensions of the print medium, but not actually using the printer. So I would like to use the printer dimensions if one is available, otherwise use defaults if the call times out.

 

I’ve considered using a TimedPromise, but as it uses Delay’s I figure it will have the same problem.

 

So I’m wondering if there is a way of timing this call out?

 

Thanks,

 

Stewart

 

 

 

Reply | Threaded
Open this post in threaded view
|

RE: [VW 7.5] Interrupting HostPrinter>>primCreatePrintJobNamed:

Stew MacLean
Message

Thanks everyone for the help - that explains it.

 

Actually, I've discovered a workaround by implementing the following (to just obtain the extent):

 

HostPrinter>> extentLandscape: aBoolean

 

      | medium extent |

 

      handle == nil ifTrue: [self privateOpen].

      "self primCreatePrintJobNamed:

                  (IOAccessor convertSimpleStringForPlatform: aString)."

      medium := HostPrintJob startJobOnPrinter: self handle: handle.

      medium setLandscape: aBoolean.

      extent := medium width asInteger @ medium height asInteger.

      medium close.

 

      ^extent

 

This also avoids the strange Vista behaviour of opening a file selection dialog.

 

However, the suggestions may come in handy if I want to handle when the user prints to a “non existent” printer.

 

Cheers,

 

Stewart

 

 

 

-----Original Message-----
From: Steven Kelly [mailto:[hidden email]]
Sent:
1 October 2007 7:41 p.m.
To: [hidden email]
Subject: RE: [VW 7.5] Interrupting HostPrinter>>primCreatePrintJobNamed:

 

You might be able to use a threaded printer call to see whether the printer is available or not. You can make that time out after a second or two, and if you haven't had an answer you know not to call the primitive. IIRC, Windows Goodies in the public store has the threaded printer calls for Windows. You probably won't need them for other platforms, since I don't imagine another platform would be as dumb as Windows :-).

 

Steve

-----Original Message-----
From: Stewart MacLean [mailto:[hidden email]]
Sent: 29. syyskuuta 2007
4:56
To: [hidden email]
Subject: [VW 7.5] Interrupting HostPrinter>>primCreatePrintJobNamed:

Hi,

 

I’m finding that

 

HostPrinter>>primCreatePrintJobNamed: aString

       <primitive: 1210>

       ^self primitiveFailed

 

is disappearing down a “black hole” for 30 seconds before the primitive fails.

 

This occurs when the computer that has the printer is switched off, and possibly with other scenarios as well.

 

I’ve tried to time the call out by using:

 

BlockClosure>> valueWithinMilliseconds: anInteger orDo: anotherBlock

 

       "Evaluate the receiver and answer the result, giving the reciever at most anInteger milliseconds to complete.

       After that, terminate execution and answer the result of anotherBlock instead."

 

       | thisProcess timer result |

 

       thisProcess := Processor activeProcess.

       timer :=

                   [(Delay forMilliseconds: anInteger) wait.

                   thisProcess interruptWith: [Tools.Trippy.TimeoutExceeded raise]]

                               forkAt: thisProcess priority + 1.

       [[result := self value] ensure: [timer terminate]]

                   on: Tools.Trippy.TimeoutExceeded

                   do: [:ex | result := anotherBlock value].

 

       ^result

 

but the Delay waits till primCreatePrintJobNamed: returns before proceeding.

 

I’m assuming that the Delay timing is somehow being stopped by the blocking HostPrinter>>primCreatePrintJobNamed: aString call.

 

In this case, I’m making the call just to get the dimensions of the print medium, but not actually using the printer. So I would like to use the printer dimensions if one is available, otherwise use defaults if the call times out.

 

I’ve considered using a TimedPromise, but as it uses Delay’s I figure it will have the same problem.

 

So I’m wondering if there is a way of timing this call out?

 

Thanks,

 

Stewart