Class: AlWorker::Fd

Inherits:
Object
  • Object
show all
Defined in:
lib/al_worker_fd.rb

Overview

ファイルディスクリプタ

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(file) ⇒ Fd

constructor

Parameters:

  • file (File)

    ファイルオブジェクト



44
45
46
47
# File 'lib/al_worker_fd.rb', line 44

def initialize( file )
  @file = file
  @mode_sync = :sync
end

Instance Attribute Details

#fileFile

Returns 対象のファイルオブジェクト.

Returns:

  • (File)

    対象のファイルオブジェクト



20
21
22
# File 'lib/al_worker_fd.rb', line 20

def file
  @file
end

#mode_syncSymbol

Returns 同期(:sync)/非同期(:async).

Returns:

  • (Symbol)

    同期(:sync)/非同期(:async)



17
18
19
# File 'lib/al_worker_fd.rb', line 17

def mode_sync
  @mode_sync
end

Class Method Details

.open(path, mode = "r") ⇒ AlWorker::Fd

Note:

ファイルオープン

簡易記述によるファクトリ

Parameters:

  • path (String)

    ファイル名

  • mode (String) (defaults to: "r")

    オープンモード

Returns:



32
33
34
35
# File 'lib/al_worker_fd.rb', line 32

def self.open( path, mode = "r" )
  file = File.open( path, mode )
  self.new( file )
end

Instance Method Details

#closeObject

クローズ



138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
# File 'lib/al_worker_fd.rb', line 138

def close()
  # (note)
  # ready_*() 中から呼び出されるブロックからコールされる可能性がある。
  # その場合、自分のスレッドをkillしないようにしている。
  # 自分のスレッドは、return後のselectで例外によって終了するだろう。
  #
  if @thread_read && @thread_read.alive? && @thread_read != Thread.current
    @thread_read.kill rescue 0
  end
  if @thread_write && @thread_write.alive? && @thread_write != Thread.current
    @thread_write.kill rescue 0
  end

  @file.close  if ! @file.closed?
end

#ready_read(*arg) { ... } ⇒ Object

読み込み準備完了時

Parameters:

  • arg (Array)

    ブロック内に渡す引数

Yields:

  • 完了時動作



56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
# File 'lib/al_worker_fd.rb', line 56

def ready_read( *arg )
  th = Thread.start( arg ) { |arg|
    loop do
      begin
        ret = IO.select( [@file] )
      rescue
        @thread_read = nil
        break
      end
      next if ! ret

      begin
        if mode_sync == :sync
          AlWorker.mutex_sync.synchronize { yield( *arg ) }
        else
          yield( *arg )
        end

      rescue Exception => ex
        raise ex  if ex.class == SystemExit
        AlWorker.log( ex )
      end
    end
  }

  #(note)
  # ready_readからready_readを呼び出されても動くように、
  # 若干の工夫がしてある。
  if @thread_read
    th_bak = @thread_read
    @thread_read = th
    th_bak.kill rescue 0
  else
    @thread_read = th
  end
end

#ready_write(*arg) { ... } ⇒ Object

書き込み準備完了時

Parameters:

  • arg (Array)

    ブロック内に渡す引数

Yields:

  • 完了時動作



100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
# File 'lib/al_worker_fd.rb', line 100

def ready_write( *arg )
  th = Thread.start( arg ) { |arg|
    loop do
      begin
        ret = IO.select( [], [@file] )
      rescue
        @thread_write = nil
        break
      end
      next if ! ret

      begin
        if mode_sync == :sync
          AlWorker.mutex_sync.synchronize { yield( *arg ) }
        else
          yield( *arg )
        end

      rescue Exception => ex
        raise ex  if ex.class == SystemExit
        AlWorker.log( ex )
      end
    end
  }

  if @thread_write
    th_bak = @thread_write
    @thread_write = th
    th_bak.kill rescue 0
  else
    @thread_write = th
  end
end