File: poll_items.rb

package info (click to toggle)
ruby-ffi-rzmq 2.0.7-1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, bullseye, forky, sid, trixie
  • size: 392 kB
  • sloc: ruby: 2,992; sh: 21; makefile: 2
file content (85 lines) | stat: -rw-r--r-- 1,877 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
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
require 'forwardable'
require 'ostruct'

module ZMQ
  class PollItems
    include Enumerable
    extend  Forwardable

    def_delegators :@pollables, :size, :empty?

    def initialize
      @pollables  = {}
      @item_size  = LibZMQ::PollItem.size
      @item_store = nil
    end

    def address
      clean
      @item_store
    end

    def get pollable
      return unless entry = @pollables[pollable]
      clean
      pointer = @item_store + (@item_size * entry.index)
      item = ZMQ::PollItem.from_pointer(pointer)
      item.pollable = pollable
      item
    end
    alias :[] :get

    def <<(poll_item)
      @dirty = true
      @pollables[poll_item.pollable] = OpenStruct.new(:index => size, :data => poll_item)
    end
    alias :push :<<

    def delete pollable
      if @pollables.delete(pollable)
        @dirty = true
        clean
        true
      else
        false
      end
    end

    def each &blk
      clean
      @pollables.each_key do |pollable|
        yield get(pollable)
      end
    end

    def inspect
      clean
      str = ""
      each { |item| str << "ptr [#{item[:socket]}], events [#{item[:events]}], revents [#{item[:revents]}], " }
      str.chop.chop
    end

    def to_s; inspect; end

    private

    # Allocate a contiguous chunk of memory and copy over the PollItem structs
    # to this block. Note that the old +@store+ value goes out of scope so when
    # it is garbage collected that native memory should be automatically freed.
    def clean
      if @dirty
        @item_store = FFI::MemoryPointer.new @item_size, size, true

        offset = 0
        @pollables.each_with_index do |(pollable, entry), index|
          entry.index = index
          LibC.memcpy(@item_store + offset, entry.data.pointer, @item_size)
          offset += @item_size
        end

        @dirty = false
      end
    end

  end
end