<div dir="ltr"><br><div class="gmail_extra"><br><br><div class="gmail_quote">2014-07-25 20:05 GMT+02:00 Eliot Miranda <span dir="ltr"><<a href="mailto:eliot.miranda@gmail.com" target="_blank">eliot.miranda@gmail.com</a>></span>:<br>
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"> <br><div dir="ltr">Hi Nicolai, Hi Ben,<br><div class="gmail_extra"><br><br><div class="gmail_quote">
On Fri, Jul 25, 2014 at 10:55 AM, Nicolai Hess <span dir="ltr"><<a href="mailto:nicolaihess@web.de" target="_blank">nicolaihess@web.de</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"> <br><div dir="ltr"><br><div class="gmail_extra">Hi Ben,<br>
<br></div><div class="gmail_extra">I am on Windows too :(<br></div><div class="gmail_extra">So, the fixes does not work (not always) on winddows too. But at least they make it less probable to occure, but it still happens.<br>
</div><div class="gmail_extra">The most distracting thing is, after the first ui lock, pressing alt+dot, closing the debuggers, pressing alt+dot ....<br>and trying to close the very first debugger, after that, it all works. The UI is responsive again and suspending the process does<br>
not block the ui anymore.<br></div><div class="gmail_extra">It "looks like" supsending the process reactivates another process that blocks the UI. And as soon as I terminate this<br>process (alt+dot, close debugger ...) all works. <br>
</div><div class="gmail_extra">But I really don't know.<br></div></div></blockquote><div><br></div><div>if you can run a unix machine (in a VM?) then remember that kill -USR1 pid will cause the VM to print out a stack backtrace of all processes in the image. That can be very useful in debuggng lockups like this.</div>
<div><br></div><div>HTH</div></div></div></div></blockquote><div><br></div><div>Ok, but I don't know if this helps, at least it does not look very helpful to me:)<br><br></div><div><br>SIGUSR1 Mon Jul 28 01:06:16 2014<br>
<br><br>pharo VM version: 3.9-7 #1 Tue May 6 08:30:23 UTC 2014 gcc 4.8.2 [Production ITHB VM]<br>Built from: NBCoInterpreter NativeBoost-CogPlugin-GuillermoPolito.19 uuid: acc98e51-2fba-4841-a965-2975997bba66 May 6 2014<br>
With: NBCogit NativeBoost-CogPlugin-GuillermoPolito.19 uuid: acc98e51-2fba-4841-a965-2975997bba66 May 6 2014<br>Revision: <a href="https://github.com/pharo-project/pharo-vm.git" target="_blank">https://github.com/pharo-project/pharo-vm.git</a> Commit: ef5832e6f70e5b24e8b9b1f4b8509a62b6c88040 Date: 2014-01-26 15:34:28 +0100 By: Esteban Lorenzano <<a href="mailto:estebanlm@gmail.com" target="_blank">estebanlm@gmail.com</a>> Jenkins build #14794<br>
Build host: Linux chindi08 2.6.24-32-xen #1 SMP Mon Dec 3 16:12:25 UTC 2012 i686 i686 i686 GNU/Linux<br>plugin path: /usr/lib/pharo-vm/ [default: /usr/lib/pharo-vm/]<br><br><br>C stack backtrace:<br>/usr/lib/pharo-vm/pharo-vm[0x809ad23]<br>
/usr/lib/pharo-vm/pharo-vm[0x809af6e]<br>[0xf7784410]<br>[0xf7784425]<br>/lib/i386-linux-gnu/libc.so.6(__select+0x2d)[0xf763691d]<br>/usr/lib/pharo-vm/pharo-vm(aioPoll+0x13d)[0x809748d]<br>/usr/lib/pharo-vm/vm-display-X11.so(+0xdc85)[0xf71d2c85]<br>
/usr/lib/pharo-vm/pharo-vm(ioRelinquishProcessorForMicroseconds+0x17)[0x8099b57]<br>/usr/lib/pharo-vm/pharo-vm[0x8070685]<br>[0xb6f8dbc3]<br>[0xb6f89700]<br>[0xb7a2650e]<br>[0xb6f895c0]<br><br><br>All Smalltalk process stacks (active first):<br>
Process 0xb88376fc priority 10<br>0xff76c830 M ProcessorScheduler class>idleProcess 0xb7306b08: a(n) ProcessorScheduler class<br>0xff76c850 I [] in ProcessorScheduler class>startUp 0xb7306b08: a(n) ProcessorScheduler class<br>
0xff76c870 I [] in BlockClosure>newProcess 0xb8837620: a(n) BlockClosure<br><br>Process 0xb8838c78 priority 50<br>0xff768830 I WeakArray class>finalizationProcess 0xb7306cd8: a(n) WeakArray class<br>0xff768850 I [] in WeakArray class>restartFinalizationProcess 0xb7306cd8: a(n) WeakArray class<br>
0xff768870 I [] in BlockClosure>newProcess 0xb8838b9c: a(n) BlockClosure<br><br>Process 0xb9148c20 priority 40<br>0xff7907b8 M [] in Semaphore>critical: 0xb82f8ef4: a(n) Semaphore<br>0xff7907d8 M BlockClosure>ensure: 0xb91502e0: a(n) BlockClosure<br>
0xff7907f8 M Semaphore>critical: 0xb82f8ef4: a(n) Semaphore<br>0xff790814 M Delay>schedule 0xb91501e4: a(n) Delay<br>0xff79082c M Delay>wait 0xb91501e4: a(n) Delay<br>0xff790850 I [] in BackgroundWorkDisplayMorph>initialize 0xb91488b0: a(n) BackgroundWorkDisplayMorph<br>
0xff790870 I [] in BlockClosure>newProcess 0xb9148b40: a(n) BlockClosure<br><br>Process 0xb7902630 priority 40<br>0xff764784 M [] in Semaphore>critical: 0xb82f8ef4: a(n) Semaphore<br>0xff7647a4 M BlockClosure>ensure: 0xb916b7a4: a(n) BlockClosure<br>
0xff7647c4 M Semaphore>critical: 0xb82f8ef4: a(n) Semaphore<br>0xff7647e0 M Delay>schedule 0xb916b6a8: a(n) Delay<br>0xff7647f8 M Delay>wait 0xb916b6a8: a(n) Delay<br>0xff764818 M WorldState>interCyclePause: 0xb75e8fd8: a(n) WorldState<br>
0xff764834 M WorldState>doOneCycleFor: 0xb75e8fd8: a(n) WorldState<br>0xff764850 M WorldMorph>doOneCycle 0xb75e8fa4: a(n) WorldMorph<br>0xff764870 I [] in MorphicUIManager()>? 0xb770ac38: a(n) MorphicUIManager<br>
0xb78cb554 s [] in BlockClosure()>?<br><br>Process 0xb82f9078 priority 80<br>0xff765858 M Delay class>handleTimerEvent 0xb8684d08: a(n) Delay class<br>0xff765870 M Delay class()>? 0xb8684d08: a(n) Delay class<br>
0xb8623474 s [] in Delay class()>?<br>0xb82f9018 s [] in BlockClosure>newProcess<br><br>Process 0xb883735c priority 60<br>0xff76680c M InputEventFetcher>waitForInput 0xb72f059c: a(n) InputEventFetcher<br>0xff766830 M InputEventFetcher>eventLoop 0xb72f059c: a(n) InputEventFetcher<br>
0xff766850 I [] in InputEventFetcher>installEventLoop 0xb72f059c: a(n) InputEventFetcher<br>0xff766870 I [] in BlockClosure>newProcess 0xb8837280: a(n) BlockClosure<br><br>Process 0xb8837534 priority 60<br>0xb8837568 s SmalltalkImage>lowSpaceWatcher<br>
0xb9127478 s [] in SmalltalkImage>installLowSpaceWatcher<br>0xb88374d4 s [] in BlockClosure>newProcess<br><br>Most recent primitives<br>relinquishProcessorForMicroseconds:<br>relinquishProcessorForMicroseconds:<br>
relinquishProcessorForMicroseconds:<br>
relinquishProcessorForMicroseconds:<br></div><div>~ 200 times<br></div><div><br> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr">
<div class="gmail_extra"><div class="gmail_quote"><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr">
<div class="gmail_extra">Nicolai<br><br></div><div class="gmail_extra"><br></div><div class="gmail_extra"><br><div class="gmail_quote">2014-07-25 16:56 GMT+02:00 Ben Coman <span dir="ltr"><<a href="mailto:btc@openinworld.com" target="_blank">btc@openinworld.com</a>></span>:<br>
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"> <br><u></u>
<div bgcolor="#ffffff" text="#000000">
Over the last few days I have been looking deeper into the image
locking when suspending a process. It is an
interesting rabbit hole [1] that leads to pondering the Delay
machinery, that leads to some VM questions. <br>
<br>
When pressing the interrupt key it seems to always opens
the debugger with the following call stack. <br>
Semaphore>>critical: 'self wait'<br>
BlockClosure>>ensure: 'self valueNoContextSwitch'<br>
Semaphore>>critical: 'ensure: [ caught ifTrue: [self signal]]<br>
Delay>>schedule 'AccessProtect critical: ['<br>
Delay>>wait 'self schedule'<br>
WorldState>>interCyclePause:<br>
<br>
I notice...<br>
Delay class >> initialize <br>
TimingSemaphore := (Smalltalk specialObjectsArray at: 30).<br>
and...<br>
Delay class >> startTimerEventLoop<br>
TimingSemaphore := Semaphore new.<br>
which seems incongruous that TimingSemaphore is set in differently. So
while I presume this critical stuff all works fine, just in an exotic
way, my entropy-guarding-neuron would just like confirm this is so.<br>
<br>
--------------<br>
<br>
In Delay class >> handleTimerEvent the comment says... <br>
"Handle a timer event.... <br>
-a timer signal (not explicitly specified)"<br>
...is that event perhaps a 'tick' generated periodically by the VM via
that item from specialObjectArray ? Or is there some other mechanism ?<br>
<br>
--------------<br>
<br>
[1] <a href="http://www.urbandictionary.com/define.php?term=Rabbit+Hole" target="_blank">http://www.urbandictionary.com/define.php?term=Rabbit+Hole</a><br>
cheers -ben<br>
<br>
<br>
P.S. I've left the following for some initial context as I change the
subject. btw Nicolai, I confirm that my proposed fixes only work on
Windows, not Mavericks (and I haven't checked Linux).<br>
<br>
Nicolai Hess wrote:
<blockquote type="cite">
<div dir="ltr"><br>
<div class="gmail_extra">Hi ben, thank you for looking at this.<br>
</div>
<div class="gmail_extra"><br>
<div class="gmail_quote">2014-07-22 20:17 GMT+02:00 <span dir="ltr"><<a href="mailto:btc@openinworld.com" target="_blank">btc@openinworld.com</a>></span>:<br>
<blockquote class="gmail_quote" style="border-left:1px solid rgb(204,204,204);margin:0px 0px 0px 0.8ex;padding-left:1ex">
<div bgcolor="#ffffff" text="#000000">
I thought this might be interesting to learn, so I've gave it a go. I
had some success at the end, but I'll give a progressive report.<br>
<br>
First I thought I'd try moving the update of StringMorph outside the
worker-process using a Morph's #step method as follows...<br>
<br>
Morph subclass: #BackgroundWorkDisplayMorph<br>
instanceVariableNames: 'interProcessString stringMorph'<br>
classVariableNames: ''<br>
category: 'BenPlay'<br>
"---------"<br>
<br>
BackgroundWorkDisplayMorph>>initializeMorph<br>
self color: Color red. <br>
stringMorph := StringMorph new.<br>
self addMorphBack: stringMorph.<br>
self extent:(300@50).<br>
"---------"<br>
<br>
BackgroundWorkDisplayMorph>>newWorkerProcess<br>
^[ <br>
| work | <br>
work := 0.<br>
[ 20 milliSeconds asDelay wait. <br>
work := work + 1.<br>
interProcessString := work asString.<br>
] repeat.<br>
] newProcess.<br>
"---------"<br>
<br>
BackgroundWorkDisplayMorph>>step<br>
stringMorph contents: interProcessString.<br>
"---------"<br>
<br>
BackgroundWorkDisplayMorph>>stepTime<br>
^50<br>
"---------"<br>
<br>
BackgroundWorkDisplayMorph>>initialize<br>
| workerProcess running |<br>
super initialize.<br>
self initializeMorph.<br>
<br>
workerProcess := self newWorkerProcess.<br>
running := false.<br>
<br>
self on: #mouseUp send: #value to: <br>
[ (running := running not)<br>
ifTrue: [ workerProcess resume. self color: Color green. ]<br>
ifFalse: [ workerProcess suspend. self color: Color red. ]<br>
]<br>
"---------"<br>
<br>
<br>
<br>
But evaluating "BackgroundWorkDisplayMorph new openInWorld" found this
exhibited the same problematic behavior you reported... Clicking on the
morph worked a few times and then froze the UI until Cmd-. pressed a
few times.<br>
</div>
</blockquote>
<blockquote class="gmail_quote" style="border-left:1px solid rgb(204,204,204);margin:0px 0px 0px 0.8ex;padding-left:1ex">
<div bgcolor="#ffffff" text="#000000"><br>
However I found the following never locked the GUI.<br>
<br>
BackgroundWorkDisplayMorph>>initialize<br>
"BackgroundWorkDisplayMorph new openInWorld"<br>
| workerProcess running |<br>
super initialize.<br>
self initializeMorph.<br>
<br>
workerProcess := self newWorkerProcess.<br>
running := false.<br>
<br>
[ [ (running := running not)<br>
ifTrue: [ workerProcess resume. self color: Color green ]<br>
ifFalse: [ workerProcess suspend. self color: Color red ].<br>
10 milliSeconds asDelay wait. <br>
] repeat ] fork.<br>
"---------"<br>
<br>
</div>
</blockquote>
<div><br>
</div>
<div>This locks the UI as well. Not every timet hough. I did this 5
times, every time in a freshly loaded image and it happens two times.<br>
</div>
<div><br>
</div>
<blockquote class="gmail_quote" style="border-left:1px solid rgb(204,204,204);margin:0px 0px 0px 0.8ex;padding-left:1ex">
<div bgcolor="#ffffff" text="#000000">So the problem seemed to not
be with #suspend/#resume or with the
shared variable /interProcessString/. Indeed, since in the worker
thread /interProcessString/ is atomically assigned a copy via
#asString, and the String never updated, I think there is no need to
surround use of it with a critical section. <br>
<br>
The solution then was to move the "#resume/#suspend" away from the
"#on: #mouseUp send: #value to:" as follows...<br>
<br>
BackgroundWorkDisplayMorph>>initialize<br>
"BackgroundWorkDisplayMorph new openInWorld"<br>
| workerProcess running lastRunning |<br>
super initialize.<br>
self initializeMorph.<br>
<br>
workerProcess := self newWorkerProcess.<br>
lastRunning := running := false.<br>
<br>
[ [ lastRunning = running ifFalse: <br>
[ running<br>
ifTrue: [ workerProcess resume ]<br>
ifFalse: [ workerProcess suspend ]. <br>
lastRunning := running.<br>
]. <br>
10 milliSeconds asDelay wait.<br>
] repeat ] fork. <br>
<br>
self on: #mouseUp send: #value to: <br>
[ (running := running not)<br>
ifTrue: [ self color: Color green. ]<br>
ifFalse: [ self color: Color red. ]<br>
]<br>
"---------"<br>
</div>
</blockquote>
<div><br>
</div>
<div>And this too :(<br>
</div>
<div><br>
</div>
<blockquote class="gmail_quote" style="border-left:1px solid rgb(204,204,204);margin:0px 0px 0px 0.8ex;padding-left:1ex">
<div bgcolor="#ffffff" text="#000000"><br>
And finally remove the busy loop.<br>
<br>
BackgroundWorkDisplayMorph>>initialize<br>
"BackgroundWorkDisplayMorph new openInWorld"<br>
| workerProcess running lastRunning semaphore |<br>
super initialize.<br>
self initializeMorph.<br>
<br>
workerProcess := self newWorkerProcess.<br>
lastRunning := running := false.<br>
semaphore := Semaphore new.<br>
<br>
[ [ semaphore wait.<br>
running<br>
ifTrue: [ workerProcess resume ]<br>
ifFalse: [ workerProcess suspend ]. <br>
] repeat ] fork. <br>
<br>
self on: #mouseUp send: #value to: <br>
[ (running := running not)<br>
ifTrue: [ self color: Color green. ]<br>
ifFalse: [ self color: Color red. ].<br>
semaphore signal.<br>
]<br>
"---------"<br>
<br>
</div>
</blockquote>
<div><br>
</div>
<div><br>
</div>
<div>And this locks the UI too. (Loaded the code 20 times, every time
after a fresh image start up. Two times I got a locked <br>
</div>
<div>ui after the first two clicks).<br>
</div>
<div>And I don't understand this code :)<br>
<br>
<br>
</div>
<blockquote class="gmail_quote" style="border-left:1px solid rgb(204,204,204);margin:0px 0px 0px 0.8ex;padding-left:1ex">
<div bgcolor="#ffffff" text="#000000">Now I can't say how close
that is to how it "should" be done. Its the
first time I used sempahores and just what I discovered hacking around.
But hey! it works :)<br>
<br>
cheers -ben
<div>
<div><br>
<br>
<br>
Nicolai Hess wrote:
<blockquote type="cite">
<div dir="ltr">
<div><span><span style="background-color:rgb(255,255,255)" title="kämpfe immernoch damit">I am still struggling with it. <br>
<br>
</span></span></div>
<span><span style="background-color:rgb(255,255,255)" title="kämpfe immernoch damit">Any ideas?<br>
</span></span></div>
<div class="gmail_extra"><br>
<br>
<div class="gmail_quote">2014-07-09 11:19 GMT+02:00 Nicolai Hess <span dir="ltr"><<a href="mailto:nicolaihess@web.de" target="_blank">nicolaihess@web.de</a>></span>:<br>
<blockquote class="gmail_quote" style="border-left:1px solid rgb(204,204,204);margin:0pt 0pt 0pt 0.8ex;padding-left:1ex">
<div dir="ltr"><br>
<div class="gmail_extra"><br>
<br>
<div class="gmail_quote">2014-07-09 2:07 GMT+02:00 Eliot
Miranda <span dir="ltr"><<a href="mailto:eliot.miranda@gmail.com" target="_blank">eliot.miranda@gmail.com</a>></span>:
<div><br>
<blockquote class="gmail_quote" style="border-left:1px solid rgb(204,204,204);margin:0pt 0pt 0pt 0.8ex;padding-left:1ex">
<div dir="ltr">Hi Nicolai,
<div class="gmail_extra"><br>
<br>
<div class="gmail_quote">
<div>
<div>On Tue, Jul 8, 2014 at 7:19 AM, Nicolai Hess <span dir="ltr"><<a href="mailto:nicolaihess@web.de" target="_blank">nicolaihess@web.de</a>></span>
wrote:<br>
<blockquote class="gmail_quote" style="border-left:1px solid rgb(204,204,204);margin:0px 0px 0px 0.8ex;padding-left:1ex">
<div dir="ltr">
<div>I want to create a process doing some work and call
#changed on a Morph.<br>
I want to start/suspend/resume or stop this process.<br>
But sometimes, suspending the process locks the UI-Process, <br>
and I don't know why. Did I miss something or do I have to care when to
call suspend?<br>
</div>
<div><br>
</div>
<div>Wrapping the "morph changed" call in<br>
</div>
<div>UIManager default defer:[ morph changed].<br>
</div>
<div>Does not change anything.<br>
</div>
<div><br>
Here is an example to reproduce it. <br>
Create the process,<br>
call resume, call supsend. It works, most of the time, <br>
but sometimes, calling suspend locks the ui.<br>
<br>
p:=[[true] whileTrue:[ Transcript crShow: (DateAndTime now asString).
30 milliSeconds asDelay wait]] newProcess. </div>
</div>
</blockquote>
<blockquote class="gmail_quote" style="border-left:1px solid rgb(204,204,204);margin:0px 0px 0px 0.8ex;padding-left:1ex">
<div dir="ltr">
<div>p resume.<br>
p suspend.<br>
</div>
</div>
</blockquote>
<div><br>
</div>
</div>
</div>
<div>If you simply suspend this process at random form a
user-priority process you'll never be able to damage the Delay
machinery you're using, but chances are you'll suspend the process
inside the critical section that Transcript uses to make itself
thread-safe, and that'll lock up the Transcript. </div>
</div>
</div>
</div>
</blockquote>
<div><br>
</div>
</div>
<div>Thank you Eliot<br>
</div>
<div>yes I guessed it locks up the critical section, but I
hoped
with would not happen if I the use UIManager defer call.<br>
</div>
<div>
<div><br>
</div>
<blockquote class="gmail_quote" style="border-left:1px solid rgb(204,204,204);margin:0pt 0pt 0pt 0.8ex;padding-left:1ex">
<div dir="ltr">
<div class="gmail_extra">
<div class="gmail_quote">
<div><br>
</div>
<div>ThreadSafeTranscript>>nextPutAll: value</div>
<div><span> </span></div>
<div><span> </span>accessSemaphore</div>
<div><span> </span>critical: [stream nextPutAll: value].</div>
<div><span> </span>^value</div>
<div><br>
</div>
<div>So instead you need to use a semaphore. e.g.</div>
<div><br>
</div>
<div>| p s wait |</div>
<div>s := Semaphore new.</div>
<div>p:=[[true] whileTrue:[wait ifTrue: [s wait]. Transcript
crShow: (DateAndTime now asString). 30 milliSeconds asDelay wait]]
newProcess.</div>
<div>wait := true.</div>
<div>30 milliSeconds asDelay wait.<br>
</div>
<div>wait := false.</div>
<div>s signal</div>
<div><br>
</div>
<div>etc...</div>
</div>
</div>
</div>
</blockquote>
<div><br>
</div>
</div>
<div>Is this a common pattern I can find in pharos classes. Or
I
need some help understanding this. The semaphore<br>
</div>
<div>wait/signal is used instead of process resume/suspend?<br>
</div>
<div><br>
What I want is a process doing repeatly some computation, <br>
calls or triggers an update on a morph, and I want to suspend and
resume this process.<br>
<br>
I would stop this discussion if someone tells me, "No your are doing it
wrong, go this way ..", BUT what strikes me:<br>
in this example, that reproduces my problem more closely:<br>
<br>
|p m s running|<br>
running:=false.<br>
m:=Morph new color:Color red.<br>
s:= StringMorph new.<br>
m addMorphBack:s.<br>
p:=[[true]whileTrue:[20 milliSeconds asDelay wait. s
contents:(DateAndTime now asString). m changed]] newProcess.<br>
m on:#mouseUp send:#value to:[<br>
running ifTrue:[p suspend. m color:Color red.]<br>
ifFalse:[p resume.m color:Color green.].<br>
running := running not].<br>
m extent:(300@50).<br>
m openInWorld<br>
<br>
<br>
</div>
<div>clicking on the morph will stop or resume the process, if
it
locks up I can still press alt+dot -><br>
</div>
<div>- a Debugger opens but the UI is still not responsive. I
can
click with the mouse on the debuggers close icon.<br>
</div>
<div>- nothing happens, as the UI is still blocked.<br>
</div>
<div>- pressing alt+Dot again, the mouse click on the close
icon is
processed and the first debugger window closes<br>
- maybe other debuggers open.<br>
<br>
Repeating this steps, at some time the system is *fully* responsive
again!<br>
</div>
<div>And miraculously, it works after that w<span lang="en"><span>ithout
further</span> <span>blockages.</span></span></div>
<div>What's happening here?<span><font color="#888888"><br>
</font></span></div>
<span><font color="#888888">
<div><br>
<br>
</div>
<div>Nicolai<br>
</div>
</font></span>
<div>
<div><br>
</div>
<blockquote class="gmail_quote" style="border-left:1px solid rgb(204,204,204);margin:0pt 0pt 0pt 0.8ex;padding-left:1ex">
<div dir="ltr">
<div class="gmail_extra">
<div class="gmail_quote">
<div><br>
</div>
<div>HTH</div>
<div><br>
</div>
<blockquote class="gmail_quote" style="border-left:1px solid rgb(204,204,204);margin:0px 0px 0px 0.8ex;padding-left:1ex">
<div dir="ltr">
<div>regards<br>
</div>
<span><font color="#888888">Nicolai<span><font color="#888888"><br>
</font></span></font></span></div>
<span></span></blockquote>
</div>
<span><font color="#888888"><br>
<br clear="all">
<div><br>
</div>
-- <br>
best,
<div>Eliot</div></font></span></div></div></blockquote></div></div></div></div></blockquote></div></div></blockquote></div></div></div></blockquote></div></div></div></blockquote></div></blockquote></div></div>
</div></blockquote></div>-- <br>Aloha,<div>Eliot</div>
</div></div>
<br></blockquote></div><br></div></div>