Tcp server with multithreading

hi.

I'm writing tcp server and I want to know:

1. how can I block thread until some event will occur w/o overhead?
(i.e. not timer, but something like semaphore);

2. how can I interrupt IO::select() call from main thread?

thank you/

···

--
Posted via http://www.ruby-forum.com/.

hi.

I'm writing tcp server and I want to know:

1. how can I block thread until some event will occur w/o overhead?
(i.e. not timer, but something like semaphore);

A Conditionariable, IO.select (which you already knew :),
or a blocking read on any socket or pipe.

2. how can I interrupt IO::select() call from main thread?

Create a socketpair or pipe and and write to it from the main thread.
It's also useful with the self-pipe trick[1]

If you're stuck on a platform without UNIX sockets or pipes, you can
also connect to your main TCPServer (or another private one) to
wakeup from select.

[1] http://cr.yp.to/docs/selfpipe.html

···

Daniel Fort <naquad@gmail.com> wrote:

--
Eric Wong

1. how can I block thread until some event will occur w/o overhead?
(i.e. not timer, but something like semaphore);

select [or in 1.9 fibers].

2. how can I interrupt IO::select() call from main thread?

You'd have to have some socket within it that will interrupt.

like interruptor = TCPSocket.new( '', 3333)

select [interruptor], nil, nil

then in other thread
a TCPSocket.new('localhost', 3333)
# to interrupt
a.send 'a'

something like that

Or if you didn't care about thread safety you could use Thread.raise
[scary].

But overall I might suggest eventmachine or revactor for what you want.
Cheers!
=r

···

--
Posted via http://www.ruby-forum.com/\.

A Conditionariable, IO.select (which you already knew :),
or a blocking read on any socket or pipe.

Creating a new socketpair/pipe is pretty too much imho (no matter it's a
very
small object, but it exists and must be handled). I thought about some
kind of
semaphore, then process would look like:

in thread:

semaphore.wait_for_event

in main:

semaphore.emit_event

Create a socketpair or pipe and and write to it from the main thread.
It's also useful with the self-pipe trick[1]

If you're stuck on a platform without UNIX sockets or pipes, you can
also connect to your main TCPServer (or another private one) to
wakeup from select.

that makes the same trouble as described above: one more file
descriptor,
which is overhead. I knew this solution and used it in C, but I thought
ruby is able to provide some better solution.

···

--
Posted via http://www.ruby-forum.com/\.

But overall I might suggest eventmachine or revactor for what you want.
Cheers!
=r

I'm using eventmachine atm, revactor seems to be easier and simpler, but
it requires 1.9 ruby :frowning:

···

--
Posted via http://www.ruby-forum.com/\.

Hi Daniel,

···

On Thu, Jul 9, 2009 at 8:28 PM, Daniel Fort <naquad@gmail.com> wrote:

> A Conditionariable, IO.select (which you already knew :),
> or a blocking read on any socket or pipe.
>
Creating a new socketpair/pipe is pretty too much imho (no matter it's a
very
small object, but it exists and must be handled). I thought about some
kind of
semaphore, then process would look like:

in thread:

semaphore.wait_for_event

in main:

semaphore.emit_event

>
> Create a socketpair or pipe and and write to it from the main thread.
> It's also useful with the self-pipe trick[1]
>
> If you're stuck on a platform without UNIX sockets or pipes, you can
> also connect to your main TCPServer (or another private one) to
> wakeup from select.

that makes the same trouble as described above: one more file
descriptor,
which is overhead. I knew this solution and used it in C, but I thought
ruby is able to provide some better solution.
--

Look up EventMachine - it's what you want without re-inventing the wheel.

John

Creating a new socketpair/pipe is pretty too much imho (no matter it's a
very
small object, but it exists and must be handled). I thought about some
kind of
semaphore, then process would look like:

in thread:

semaphore.wait_for_event

in main:

semaphore.emit_event

I've found the way how to do this, here is code + example:

#!/usr/bin/ruby -w

require 'thread'

class MassSemaphoreEmulator
  def initialize
    @mutex=Mutex.new # we can have race condition on a variable below,
so avoid it with mutex
    @waiting_threads=
  end

  def wait
    @mutex.synchronize { @waiting_threads<<Thread.current } # add
current thread to waiting ones
    Thread.stop
  end

  def signal
    @mutex.synchronize do # wakeup all threads
      @waiting_threads.each {|t| t.wakeup}
      @waiting_threads.clear
    end
  end
end

semaphore=MassSemaphoreEmulator.new

threads=(1..10).map do |i|
  Thread.new(i*1) do |v|
    print "#{v} is waiting...\n"
    semaphore.wait # wait for our mutex
    print "#{v} got signal.\n"
  end
end

semaphore.signal # get all waiting threads up

threads.each {|t| t.join}

I've also tried to do something with ConditionalVariable, but no luck,
it didn't stop waiting threads.

now I need to find a way for interrupting select call

···

--
Posted via http://www.ruby-forum.com/\.

Look up EventMachine - it's what you want without re-inventing the
wheel.

John

thank you, thats exaclty what I need :slight_smile:

···

--
Posted via http://www.ruby-forum.com/\.