Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 13 additions & 17 deletions ext/objspace/objspace.c
Original file line number Diff line number Diff line change
Expand Up @@ -108,28 +108,24 @@ each_object_with_flags(each_obj_with_flags cb, void *ctx)

/*
* call-seq:
* ObjectSpace.memsize_of_all([klass]) -> Integer
* ObjectSpace.memsize_of_all(klass = nil) -> integer
*
* Return consuming memory size of all living objects in bytes.
* Returns the total memory size of all living objects in bytes.
*
* If +klass+ (should be Class object) is given, return the total memory size
* of instances of the given class.
* ObjectSpace.memsize_of_all # => 12502001
*
* Note that the returned size is incomplete. You need to deal with this
* information as only a *HINT*. Especially, the size of +T_DATA+ may not be
* correct.
*
* Note that this method does *NOT* return total malloc'ed memory size.
* If +klass+ is given (which must be a Class or Module), returns the total
* memory size of objects whose class is, or is a subclass, of +klass+.
*
* This method can be defined by the following Ruby code:
* class MyClass; end
* ObjectSpace.memsize_of_all(MyClass) # => 0
* o = MyClass.new
* ObjectSpace.memsize_of_all(MyClass) # => 40
*
* def memsize_of_all klass = false
* total = 0
* ObjectSpace.each_object{|e|
* total += ObjectSpace.memsize_of(e) if klass == false || e.kind_of?(klass)
* }
* total
* end
* Note that the value returned may be an underestimate of the actual amount
* of memory used. Therefore, the value returned should only be used as a hint,
* rather than a source of truth. In particular, the size of +T_DATA+ objects may
* not be correct.
*
* This method is only expected to work with C Ruby.
*/
Expand Down
26 changes: 13 additions & 13 deletions lib/timeout.rb
Original file line number Diff line number Diff line change
Expand Up @@ -212,17 +212,17 @@ def self.synchronize(mutex, &block)
# value of 0 or +nil+ will execute the block without any timeout.
# Any negative number will raise an ArgumentError.
# +klass+:: Exception Class to raise if the block fails to terminate
# in +sec+ seconds. Omitting will use the default, Timeout::Error
# in +sec+ seconds. Omitting will use the default, Timeout::Error.
# +message+:: Error message to raise with Exception Class.
# Omitting will use the default, "execution expired"
# Omitting will use the default, <tt>"execution expired"</tt>.
#
# Returns the result of the block *if* the block completed before
# +sec+ seconds, otherwise raises an exception, based on the value of +klass+.
#
# The exception raised to terminate the given block is the given +klass+, or
# Timeout::ExitException if +klass+ is not given. The reason for that behavior
# is that Timeout::Error inherits from RuntimeError and might be caught unexpectedly by `rescue`.
# Timeout::ExitException inherits from Exception so it will only be rescued by `rescue Exception`.
# is that Timeout::Error inherits from RuntimeError and might be caught unexpectedly by +rescue+.
# Timeout::ExitException inherits from Exception so it will only be rescued by <tt>rescue Exception</tt>.
# Note that the Timeout::ExitException is translated to a Timeout::Error once it reaches the Timeout.timeout call,
# so outside that call it will be a Timeout::Error.
#
Expand All @@ -231,21 +231,21 @@ def self.synchronize(mutex, &block)
# For those reasons, this method cannot be relied on to enforce timeouts for untrusted blocks.
#
# If a scheduler is defined, it will be used to handle the timeout by invoking
# Scheduler#timeout_after.
# Fiber::Scheduler#timeout_after.
#
# Note that this is both a method of module Timeout, so you can <tt>include
# Timeout</tt> into your classes so they have a #timeout method, as well as
# a module method, so you can call it directly as Timeout.timeout().
#
# ==== Ensuring the exception does not fire inside ensure blocks
#
# When using Timeout.timeout it can be desirable to ensure the timeout exception does not fire inside an +ensure+ block.
# The simplest and best way to do so it to put the Timeout.timeout call inside the body of the begin/ensure/end:
# When using Timeout.timeout, it can be desirable to ensure the timeout exception does not fire inside an +ensure+ block.
# The simplest and best way to do so is to put the Timeout.timeout call inside the body of the +begin+/+ensure+/+end+:
#
# begin
# Timeout.timeout(sec) { some_long_operation }
# ensure
# cleanup # safe, cannot be interrupt by timeout
# cleanup # safe, cannot be interrupted by timeout
# end
#
# If that is not feasible, e.g. if there are +ensure+ blocks inside +some_long_operation+,
Expand All @@ -263,17 +263,17 @@ def self.synchronize(mutex, &block)
# end
# }
#
# An important thing to note is the need to pass an exception klass to Timeout.timeout,
# otherwise it does not work. Specifically, using +Thread.handle_interrupt(Timeout::ExitException => ...)+
# An important thing to note is the need to pass an exception +klass+ to Timeout.timeout,
# otherwise it does not work. Specifically, using <tt>Thread.handle_interrupt(Timeout::ExitException => ...)</tt>
# is unsupported and causes subtle errors like raising the wrong exception outside the block, do not use that.
#
# Note that Thread.handle_interrupt is somewhat dangerous because if setup or cleanup hangs
# then the current thread will hang too and the timeout will never fire.
# Also note the block might run for longer than +sec+ seconds:
# e.g. some_long_operation executes for +sec+ seconds + whatever time cleanup takes.
# e.g. +some_long_operation+ executes for +sec+ seconds + whatever time cleanup takes.
#
# If you want the timeout to only happen on blocking operations one can use :on_blocking
# instead of :immediate. However, that means if the block uses no blocking operations after +sec+ seconds,
# If you want the timeout to only happen on blocking operations, one can use +:on_blocking+
# instead of +:immediate+. However, that means if the block uses no blocking operations after +sec+ seconds,
# the block will not be interrupted.
def self.timeout(sec, klass = nil, message = nil, &block) #:yield: +sec+
return yield(sec) if sec == nil or sec.zero?
Expand Down