[#23805] net/smtp — 佐藤 大輔 <densuke@...2.so-net.ne.jp>

佐藤です。

26 messages 2000/07/12
[#23806] Re: net/smtp — matz@... (Yukihiro Matsumoto) 2000/07/12

まつもと ゆきひろです

[#23808] Re: net/smtp — 佐藤 大輔 <densuke@...2.so-net.ne.jp> 2000/07/12

佐藤です。

[#23809] Re: net/smtp — matz@... (Yukihiro Matsumoto) 2000/07/12

まつもと ゆきひろです

[#23811] Re: net/smtp — Minero Aoki <aamine@...> 2000/07/12

あおきです。

[#23812] Re: net/smtp — matz@... (Yukihiro Matsumoto) 2000/07/12

まつもと ゆきひろです

[#23890] Ruby Entry Package and cygwin1.dll — Noritsugu Nakamura <nnakamur@...>

25 messages 2000/07/18
[#23895] Re: Ruby Entry Package and cygwin1.dll — WATANABE Hirofumi <eban@...> 2000/07/18

わたなべです.

[#23896] Re: Ruby Entry Package and cygwin1.dll — Noritsugu Nakamura <nnakamur@...> 2000/07/18

[#23897] Re: Ruby Entry Package and cygwin1.dll — Katsuyuki Komatsu <komatsu@...> 2000/07/19

小松です。

[#23898] Re: Ruby Entry Package and cygwin1.dll — WATANABE Hirofumi <eban@...> 2000/07/19

わたなべです.

[#23899] Re: Ruby Entry Package and cygwin1.dll — Katsuyuki Komatsu <komatsu@...> 2000/07/19

小松です。

[#23923] Re: [ruby-dev:10353] Re: should prohibit `module_function' for class Class — Masatoshi SEKI <m_seki@...>

11 messages 2000/07/19

[#23940] String#unpack と scanf の関係 — kiwamu <kiwamu@...>

こんにちは。岡部@東京都立大学と申します。

16 messages 2000/07/20

[ruby-list:23787] Re: context switch during finalizer(Re: Re: Flyweight)

From: Masatoshi SEKI <m_seki@...>
Date: 2000-07-10 16:30:09 UTC
List: ruby-list #23787
咳といいます。

> なるほど。多くのライブラリはあんまりスレッドのことを考慮せず
> に書いてあります、かもしれません。スレッド標準装備をうたって
> るんだから、もうちょっとスレッド対応が簡単な方がよいかも。
> Javaのsyncronized構文とか導入した方が良いのかなあ。

どうなんでしょう。
最近 mutex_m.rb を改造して遊んでました。

(1) synchronize 中、そのスレッドは synchronize 可能 な synchronize

(2) synchronize 中でないと例外を発生させる in_synchronize

(3) attr_reader/writer/accessor のようなもので
    同期する synchronize_reader/writer/accessor や
    lockしてないと例外を発生させる lock_reader/writer/accessor

(4) メソッドを alias して同じ名前で synchronize do ... end を def する
    synchronized

などを追加してみました。
どれがアプリを書くときに有効か、いろいろ試してるところです。
# (3),(4)の実装がちょっと怪しいけどそれなりに動いてます。

mutex_m の様にオブジェクト自身に lock をかける場合、
(1) があるとややうれしいかも。
深く考えずにメソッドの中をsynchronize do .. end できるので。


# 使用例
  class Foo
    include MutexO_m

    def initialize
      super
      @foo = nil
      @bar = nil
      @count = 0
    end
    synchronize_accessor(:foo)	# synchronizeする accessor
    lock_accessor("bar")	# lockしてないと例外が起きる accessor

    def commit
      in_synchronize		# lockしてないと例外が起きるよ!
      p [@foo, @bar]
    end

    def sleep_and_set	    	# 強引なサンプル
      sleep 0.5
      @foo = @foo + @foo
      sleep 0.5
      @bar = @bar + @foo
      [@foo, @bar]
    end

    synchronized :sleep_and_set	# synchronizeで同期されます。
  end

  f = Foo.new
  f.foo = 1
  p f
  f.synchronize do 
    f.foo = 3		# 二重に synchronizeするけど平気 
    f.bar = 2		# synchronize中なので例外起きない
    f.commit
  end
  p f
  begin
    f.bar = 4		# lockしてないので例外
  rescue ThreadError
    p $!
  end
  p f

  Thread.new do
    p f.sleep_and_set	# synchronizedしてあるので安全
  end
  sleep 0.2
  f.foo = 5		# sleep_and_set が完了してから変更

  sleep 2
  p f


-- mutexo_m.rb
module MutexO_m
  def MutexO_m.append_features(cl)
    super
    unless cl.instance_of?(Module)
      cl.module_eval %q{
	alias locked? mu_locked?
	alias lock mu_lock
	alias unlock mu_unlock
	alias try_lock mu_try_lock
	alias synchronize mu_synchronize
	alias in_synchronize mu_in_synchronize
      }
    end
    def cl.synchronize_reader(attr)
      begin
	attr = attr.id2name
      rescue NameError
      end
      module_eval("def #{attr}; synchronize do return @#{attr} end; end")
    end
    def cl.synchronize_writer(attr)
      begin
	attr = attr.id2name
      rescue NameError
      end
      module_eval("def #{attr}=(p); synchronize do @#{attr}=p end; end")
    end
    def cl.synchronize_accessor(attr)
      synchronize_reader(attr)      
      synchronize_writer(attr)
    end

    def cl.lock_reader(attr)
      begin
	attr = attr.id2name
      rescue NameError
      end
      module_eval("def #{attr}; mu_in_synchronize; return @#{attr}; end")
    end
    def cl.lock_writer(attr)
      begin
	attr = attr.id2name
      rescue NameError
      end
      module_eval("def #{attr}=(p); mu_in_synchronize; @#{attr}=p ; end")
    end
    def cl.lock_accessor(attr)
      lock_reader(attr)
      lock_writer(attr)
    end

    def cl.synchronized(method)
      begin
	method = method.id2name
      rescue NameError
      end
      org = "_mu_#{method}"
      module_eval("alias #{org} #{method}")
      module_eval("def #{method}; synchronize do #{org} end; end")
      private(org)
    end
    return self
  end
  
  def MutexO_m.extend_object(obj)
    super
    obj.mu_extended
  end

  def mu_extended
    unless (defined? locked? and
	    defined? lock and
	    defined? unlock and
	    defined? try_lock and
	    defined? synchronize)
      eval "class << self
	alias locked? mu_locked?
	alias lock mu_lock
	alias unlock mu_unlock
	alias try_lock mu_try_lock
	alias synchronize mu_synchronize
	alias in_synchronize mu_in_synchronize
      end"
    end
    initialize
  end
  
  # locking 
  def mu_synchronize
    return yield if @mu_locked == Thread.current
    begin
      mu_lock
      yield
    ensure
      mu_unlock
    end
  end
  
  def mu_locked?
    @mu_locked ? true : false
  end
  
  def mu_try_lock
    result = false
    Thread.critical = true
    unless @mu_locked
      @mu_locked = Thread.current
      result = true
    end
    Thread.critical = false
    result
  end

  def mu_lock
    while (Thread.critical = true; @mu_locked)
      @mu_waiting.push Thread.current
      Thread.stop
    end
    @mu_locked = Thread.current
    mu_on_lock
    Thread.critical = false
    self
  end
  
  def mu_unlock
    return unless @mu_locked
    Thread.critical = true
    wait = @mu_waiting
    @mu_waiting = []
    @mu_locked = nil
    mu_on_unlock
    Thread.critical = false
    for w in wait
      w.run
    end
    self
  end

  def mu_in_synchronize
    raise(ThreadError, 'no lock') unless @mu_locked == Thread.current
  end

  private
  # fook
  def mu_on_lock
  end

  def mu_on_unlock
  end
  
  def initialize(*args)
    ret = super
    @mu_waiting = []
    @mu_locked = nil
    return ret
  end
end




In This Thread