Module: Orocos::MQueue

Defined in:
lib/orocos/mqueue.rb,
ext/rorocos/rorocos.cc

Overview

Support for the POSIX Message Queues transport in RTT

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.auto_fallback_to_corba?Object

:method:auto_fallback_to_corba? :call-seq:

Orocos::MQueue.auto_fallback_to_corba? => true or false
Orocos::MQueue.auto_fallback_to_corba = new_value

If true (the default), a failed connection that is using MQ will only generate a warning, and a CORBA connection will be created instead.

While orocos.rb tries very hard to not create MQ connections if it is not possible, it is hard to predict how much memory all existing MQueues in a system take, which is bounded by per-user limits or even by the amount of available kernel memory.

If false, an exception is generated instead.



124
# File 'lib/orocos/mqueue.rb', line 124

attr_predicate :auto_fallback_to_corba?, true

.auto_sizes?Object

:method:auto_sizes? :call-seq:

Orocos::MQueue.auto_sizes? => true or false
Orocos::MQueue.auto_sizes = new_value

Controls whether orocos.rb should compute the required data size for policies where MQ is used and data_size is 0. Turning it off means that you rely on the component developpers to call setDataSample in their components with a sufficiently big sample.

See the documentation of Orocos.auto? for the constraints on MQ usage. Setting this off and automatic MQ usage on is not robust and therefore not recommended.



89
# File 'lib/orocos/mqueue.rb', line 89

attr_predicate :auto_sizes?, true

.available?Boolean

Returns true if the MQ transport is available on this system (i.e. built in RTT)

Returns:

  • (Boolean)


14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# File 'lib/orocos/mqueue.rb', line 14

def self.available?
    if @available.nil?
        @available=
            if !defined?(RTT_TRANSPORT_MQ_ID)
                false
            elsif error = MQueue.try_mq_open
                Orocos.warn "the RTT is built with MQ support, but creating message queues fails with: #{error}"
                false
            elsif TRANSPORT_MQ != RTT_TRANSPORT_MQ_ID
                raise InternalError, "hardcoded value of TRANSPORT_MQ differs from the transport ID from RTT (#{TRANSPORT_MQ} != #{RTT_TRANSPORT_MQ_ID}. Set the value at the top of #{File.expand_path(__FILE__)} to #{RTT_TRANSPORT_MQ_ID} and report to the orocos.rb developers"
            else
                true
            end
    else
        @available
    end
end

.msg_maxObject

Returns the maximum message queue size, in the number of samples



158
159
160
161
162
163
164
165
166
167
168
# File 'lib/orocos/mqueue.rb', line 158

def self.msg_max
    if !@msg_max.nil?
        return @msg_max
    end

    if !File.readable?('/proc/sys/fs/mqueue/msg_max')
        @msg_max = false
    else
        @msg_max = Integer(File.read('/proc/sys/fs/mqueue/msg_max').chomp)
    end
end

.msgsize_maxObject

Returns the maximum message size allowed in a message queue, in bytes



171
172
173
174
175
176
177
178
179
180
181
# File 'lib/orocos/mqueue.rb', line 171

def self.msgsize_max
    if !@msgsize_max.nil?
        return @msgsize_max
    end

    if !File.readable?('/proc/sys/fs/mqueue/msgsize_max')
        @msgsize_max = false
    else
        @msgsize_max = Integer(File.read('/proc/sys/fs/mqueue/msgsize_max').chomp)
    end
end

.Orocos::MQueue.transportable_type_namesObject

Returns an array of string that are the type names which can be transported over the MQ layer



582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
# File 'ext/rorocos/rorocos.cc', line 582

static VALUE mqueue_transportable_type_names(VALUE mod)
{
    RTT::types::TypeInfoRepository::shared_ptr rtt_types =
        RTT::types::TypeInfoRepository::Instance();

    VALUE result = rb_ary_new();
    vector<string> all_types = rtt_types->getTypes();
    for (vector<string>::iterator it = all_types.begin(); it != all_types.end(); ++it)
    {
        RTT::types::TypeInfo* ti = rtt_types->type(*it);
        vector<int> transports = ti->getTransportNames();
        if (find(transports.begin(), transports.end(), ORO_MQUEUE_PROTOCOL_ID) != transports.end())
            rb_ary_push(result, rb_str_new2(it->c_str()));
    }
    return result;
}

.try_mq_openObject



556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
# File 'ext/rorocos/rorocos.cc', line 556

static VALUE try_mq_open(VALUE mod)
{
    int this_pid = getpid();
    std::string queue_name = std::string("/orocosrb_") + boost::lexical_cast<std::string>(this_pid);

    mq_attr attributes;
    attributes.mq_flags = 0;
    attributes.mq_maxmsg = 1;
    attributes.mq_msgsize = 1;
    mqd_t setup = mq_open(queue_name.c_str(), O_RDWR | O_CREAT, S_IREAD | S_IWRITE, &attributes);
    if (setup == -1)
        return rb_str_new2(strerror(errno));
    else
    {
        mq_close(setup);
        mq_unlink(queue_name.c_str());
        return Qnil;
    }
}

.valid_sizes?(buffer_size, data_size) ⇒ Boolean

Verifies that the given buffer size (in samples) and sample size (in bytes) are below the limits defined in /proc

This is used by Port.handle_mq_transport if MQueue.validate_sizes? is true.

Returns:

  • (Boolean)


137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
# File 'lib/orocos/mqueue.rb', line 137

def self.valid_sizes?(buffer_size, data_size)
    if !msg_max || !msgsize_max
        Orocos.warn "the system-level MQ limits msg_max and msgsize_max parameters are unknown on this OS. I am disabling MQ support"
        return false
    end

    if buffer_size > msg_max
        msg = yield if block_given?
        Orocos.warn "#{msg}: required buffer size #{buffer_size} is greater than the maximum that the system allows (#{msg_max}). On linux systems, you can use /proc/sys/fs/mqueue/msg_max to change this limit"
        return false
    end

    if data_size > msgsize_max
        msg = yield if block_given?
        Orocos.warn "#{msg}: required sample size #{data_size} is greater than the maximum that the system allows (#{msgsize_max}). On linux systems, you can use /proc/sys/fs/mqueue/msgsize_max to change this limit"
        return false
    end
    return true
end

.validate_sizes?Object

:method:validate_sizes? :call-seq:

Orocos::MQueue.validate_sizes? => true or false
Orocos::MQueue.validate_sizes = new_value

Controls whether orocos.rb should validate the data_size field in the policies that require the use of MQ. If true, verify that this size is compatible with the current operating systems limits, and switch back to CORBA if it is not the case (or if the limits are unknown).

See the documentation of Orocos.auto? for the constraints on MQ usage. Setting this off and automatic MQ usage on is not robust and therefore not recommended.



106
# File 'lib/orocos/mqueue.rb', line 106

attr_predicate :validate_sizes?, true

.warn?Object

:method:warn? :call-seq:

Orocos::MQueue.warn? => true or false
Orocos::MQueue.warn = new_value

Controls whether orocos.rb should issue a warning if auto_use? is true but some connection cannot use the message queues

See the documentation of Orocos.auto_use? for the constraints on MQ usage.



73
# File 'lib/orocos/mqueue.rb', line 73

attr_predicate :warn?, true

Instance Method Details

#auto=(value) ⇒ Object



55
56
57
58
59
# File 'lib/orocos/mqueue.rb', line 55

def auto=(value)
    if value
        raise ArgumentError, "cannot turn automatic MQ handling. It is either not built into the RTT, or you don't have enough permissions to create message queues (in which case a warning message has been displayed)"
    end
end

#auto?Boolean

Returns:

  • (Boolean)


54
# File 'lib/orocos/mqueue.rb', line 54

def auto?; false end