Bug #4463
closed[PATCH] release GVL for fcntl() for operations that may block
Added by normalperson (Eric Wong) over 13 years ago. Updated over 13 years ago.
Description
=begin
Users of F_SETLKW may block the entire VM via IO#fcntl,
release the GVL so other operations may continue.
=end
Files
0001-release-GVL-for-fcntl-for-operations-that-may-block.patch (1.7 KB) 0001-release-GVL-for-fcntl-for-operations-that-may-block.patch | normalperson (Eric Wong), 03/03/2011 06:58 PM |
Updated by kosaki (Motohiro KOSAKI) over 13 years ago
- ruby -v changed from ruby 1.9.3dev (2011-03-03 trunk 31011) [x86_64-linux] to -
=begin
Issue #4463 has been reported by Eric Wong.
Bug #4463: [PATCH] release GVL for fcntl() for operations that may block
http://redmine.ruby-lang.org/issues/4463Author: Eric Wong
Status: Open
Priority: Normal
Assignee:
Category: core
Target version: 1.9.x
ruby -v: ruby 1.9.3dev (2011-03-03 trunk 31011) [x86_64-linux]Users of F_SETLKW may block the entire VM via IO#fcntl,
release the GVL so other operations may continue.
Yeah.
It looks reasonable request. :)
=end
Updated by kosaki (Motohiro KOSAKI) over 13 years ago
=begin
Hi
2011/3/3 KOSAKI Motohiro kosaki.motohiro@gmail.com:
Issue #4463 has been reported by Eric Wong.
Bug #4463: [PATCH] release GVL for fcntl() for operations that may block
http://redmine.ruby-lang.org/issues/4463Author: Eric Wong
Status: Open
Priority: Normal
Assignee:
Category: core
Target version: 1.9.x
ruby -v: ruby 1.9.3dev (2011-03-03 trunk 31011) [x86_64-linux]Users of F_SETLKW may block the entire VM via IO#fcntl,
release the GVL so other operations may continue.Yeah.
It looks reasonable request. :)
Hi
I've commited slightly modified version today (r31025).
The difference is,
- All IO.fcntl() and IO.iocntl() relese GVL instead only SETLCKW. because,
A) if a user are using network filesystem, almost all fcntl need network
communication. iow, they can be blocked.
B) We are sure ioctl() has similar issue. But, we don't have any knowledge
which ioctl can be blocked. It is strongly dependend a
platform and a device. - Added small test. It is based on your Fcntl::Flock patch.
Thanks.
=end
Updated by normalperson (Eric Wong) over 13 years ago
=begin
KOSAKI Motohiro kosaki.motohiro@gmail.com wrote:
Hi
I've commited slightly modified version today (r31025).
The difference is,
- All IO.fcntl() and IO.iocntl() relese GVL instead only SETLCKW. because,
A) if a user are using network filesystem, almost all fcntl need network
communication. iow, they can be blocked.
B) We are sure ioctl() has similar issue. But, we don't have any knowledge
which ioctl can be blocked. It is strongly dependend a
platform and a device.
Agreed on both points.
- Added small test. It is based on your Fcntl::Flock patch.
Any chance of that patch making it into trunk? I'd be happy to make
any changes/improvements necessary (+docs, too). Thanks again.
--
Eric Wong
=end
Updated by kosaki (Motohiro KOSAKI) over 13 years ago
=begin
Hi
I've commited slightly modified version today (r31025).
The difference is,
- All IO.fcntl() and IO.iocntl() relese GVL instead only SETLCKW. because,
  A) if a user are using network filesystem, almost all fcntl need network
    communication. iow, they can be blocked.
  B) We are sure ioctl() has similar issue. But, we don't have any knowledge
    which ioctl can be blocked. It is strongly dependend a
platform and a device.Agreed on both points.
thank you.
- Added small test. It is based on your Fcntl::Flock patch.
Any chance of that patch making it into trunk? Â I'd be happy to make
any changes/improvements necessary (+docs, too). Â Thanks again.
Umm..
I don't like its interface so much. your flock object don't mange any lock
state. it's merely wrapper of argument of fcntl. your interface mean we need
two line every lock operation. eg.
lock
=end
Updated by normalperson (Eric Wong) over 13 years ago
=begin
KOSAKI Motohiro kosaki.motohiro@gmail.com wrote:
Umm..
I don't like its interface so much. your flock object don't mange any lock
state. it's merely wrapper of argument of fcntl. your interface mean we need
two line every lock operation. eg.lock = Fcntl::Flock.new Fcntl::F_WRLCK f.fcntl Fcntl::F_SETLKW, lock
I agree it's currently too verbose.
I tried to keep io.c the same so I used a String subclass. Maybe I
should just modify teach io.c to deal with Hash/Array arguments? I do
worry about placing more burden on io.c for portability reasons, though
POSIX file locks might be very common by now...
To shorten interface, maybe Fcntl::Flock[] can return an array for splat
and take symbol args (like new Socket):
f.fcntl *Fcntl::Flock[:F_SETLKW, :F_WRLCK, :SEEK_SET, 0, 0]
Or maybe even:
f.fcntl *Fcntl::Flock[:SETLKW, :WRLCK, :SET, 0, 0]
but I personally prefer array or hash capsulation. e.g
f.fcntl Fcntl:F_SETLKW, [Fcntl:F_WRLK, SEEK_SET, 0, 0]
or
f.fcntl Fcntl:F_SETLKW, { :l_type => Fcntl:F_WRLK }
Yes, I like the Hash one but requires modifying io.c with potentially
unportable code to support.
If we use non-String, maybe just call fcntl(2) inside ext/fcntl/fcntl.c
internally and forget about IO#fcntl in io.c entirely:
Fcntl::Flock[:WRLCK, :SET, 0, 0].lock(io)
Fcntl::Flock[:WRLCK, :SET, 0, 0].try_lock(io)
Fcntl::Flock[:SET, 0, 0].unlock(io)
Or even:
Fcntl.lock(io, :WRLCK, :SET, 0, 0)
Fcntl.try_lock(io, :WRLCK, :SET, 0, 0)
Fcntl.unlock(io, :SET, 0, 0)
Fcntl.getlock(io, :RDLCK, :SET, 0, 0) -> Fcntl::Flock object
That would allow us to do something stateful like:
Fcntl.synchronize(io, :WRLCK, :SET, 0, 0) do
# ...
end
I dislike all caps, even, taking hints from pthread_rwlock_*:
Fcntl.rdlock(io, :set, 0, 0)
Fcntl.tryrdlock(io, :set, 0, 0)
Fcntl.wrlock(io, :set, 0, 0)
Fcntl.trywrlock(io, :set, 0, 0)
Fcntl.unlock(io, :set, 0, 0)
Fcntl.read_synchronize(io, :set, 0, 0) do
# ...
end
Fcntl.synchronize(io, :set, 0, 0) do
# ...
end
But, of cource, I'm not against if matz ack yours. So I recommend you
describe the detailed interface to matz instead only just attached a patch.
It's best practice to persuade very busy person. :)
Thanks again for the feedback. So many ways to do this interface,
but just anything but Array#pack sounds good to me :)
--
Eric Wong
=end
Updated by kosaki (Motohiro KOSAKI) over 13 years ago
- Status changed from Open to Closed
=begin
=end
Updated by normalperson (Eric Wong) over 13 years ago
=begin
Eric Wong normalperson@yhbt.net wrote:
KOSAKI Motohiro kosaki.motohiro@gmail.com wrote:
Umm..
I don't like its interface so much. your flock object don't mange any lock
state. it's merely wrapper of argument of fcntl. your interface mean we need
two line every lock operation. eg.That would allow us to do something stateful like:
Fcntl.synchronize(io, :WRLCK, :SET, 0, 0) do
...¶
end
Following up, I went with something along these lines here.
http://redmine.ruby-lang.org/issues/4464
http://redmine.ruby-lang.org/attachments/1540/0001-add-Fcntl-Lock-object-for-easier-use-of-POSIX-file-l.patch
Simple use case to lock the whole file is just:
Fcntl::Lock.synchronize(file) do
# ...
end
--
Eric Wong
=end
Updated by kosaki (Motohiro KOSAKI) over 13 years ago
=begin
Issue #4463 has been reported by Eric Wong.
Bug #4463: [PATCH] release GVL for fcntl() for operations that may block
http://redmine.ruby-lang.org/issues/4463Author: Eric Wong
Status: Open
Priority: Normal
Assignee:
Category: core
Target version: 1.9.x
ruby -v: ruby 1.9.3dev (2011-03-03 trunk 31011) [x86_64-linux]Users of F_SETLKW may block the entire VM via IO#fcntl,
release the GVL so other operations may continue.
Yeah.
It looks reasonable request. :)
=end
Updated by kosaki (Motohiro KOSAKI) over 13 years ago
=begin
Hi
2011/3/3 KOSAKI Motohiro kosaki.motohiro@gmail.com:
Issue #4463 has been reported by Eric Wong.
Bug #4463: [PATCH] release GVL for fcntl() for operations that may block
http://redmine.ruby-lang.org/issues/4463Author: Eric Wong
Status: Open
Priority: Normal
Assignee:
Category: core
Target version: 1.9.x
ruby -v: ruby 1.9.3dev (2011-03-03 trunk 31011) [x86_64-linux]Users of F_SETLKW may block the entire VM via IO#fcntl,
release the GVL so other operations may continue.Yeah.
It looks reasonable request. :)
Hi
I've commited slightly modified version today (r31025).
The difference is,
- All IO.fcntl() and IO.iocntl() relese GVL instead only SETLCKW. because,
A) if a user are using network filesystem, almost all fcntl need network
communication. iow, they can be blocked.
B) We are sure ioctl() has similar issue. But, we don't have any knowledge
which ioctl can be blocked. It is strongly dependend a
platform and a device. - Added small test. It is based on your Fcntl::Flock patch.
Thanks.
=end
Updated by normalperson (Eric Wong) over 13 years ago
=begin
KOSAKI Motohiro kosaki.motohiro@gmail.com wrote:
Hi
I've commited slightly modified version today (r31025).
The difference is,
- All IO.fcntl() and IO.iocntl() relese GVL instead only SETLCKW. because,
A) if a user are using network filesystem, almost all fcntl need network
communication. iow, they can be blocked.
B) We are sure ioctl() has similar issue. But, we don't have any knowledge
which ioctl can be blocked. It is strongly dependend a
platform and a device.
Agreed on both points.
- Added small test. It is based on your Fcntl::Flock patch.
Any chance of that patch making it into trunk? I'd be happy to make
any changes/improvements necessary (+docs, too). Thanks again.
--
Eric Wong
=end
Updated by kosaki (Motohiro KOSAKI) over 13 years ago
=begin
Hi
I've commited slightly modified version today (r31025).
The difference is,
- All IO.fcntl() and IO.iocntl() relese GVL instead only SETLCKW. because,
  A) if a user are using network filesystem, almost all fcntl need network
    communication. iow, they can be blocked.
  B) We are sure ioctl() has similar issue. But, we don't have any knowledge
    which ioctl can be blocked. It is strongly dependend a
platform and a device.Agreed on both points.
thank you.
- Added small test. It is based on your Fcntl::Flock patch.
Any chance of that patch making it into trunk? Â I'd be happy to make
any changes/improvements necessary (+docs, too). Â Thanks again.
Umm..
I don't like its interface so much. your flock object don't mange any lock
state. it's merely wrapper of argument of fcntl. your interface mean we need
two line every lock operation. eg.
lock
=end
Updated by normalperson (Eric Wong) over 13 years ago
=begin
KOSAKI Motohiro kosaki.motohiro@gmail.com wrote:
Umm..
I don't like its interface so much. your flock object don't mange any lock
state. it's merely wrapper of argument of fcntl. your interface mean we need
two line every lock operation. eg.lock = Fcntl::Flock.new Fcntl::F_WRLCK f.fcntl Fcntl::F_SETLKW, lock
I agree it's currently too verbose.
I tried to keep io.c the same so I used a String subclass. Maybe I
should just modify teach io.c to deal with Hash/Array arguments? I do
worry about placing more burden on io.c for portability reasons, though
POSIX file locks might be very common by now...
To shorten interface, maybe Fcntl::Flock[] can return an array for splat
and take symbol args (like new Socket):
f.fcntl *Fcntl::Flock[:F_SETLKW, :F_WRLCK, :SEEK_SET, 0, 0]
Or maybe even:
f.fcntl *Fcntl::Flock[:SETLKW, :WRLCK, :SET, 0, 0]
but I personally prefer array or hash capsulation. e.g
f.fcntl Fcntl:F_SETLKW, [Fcntl:F_WRLK, SEEK_SET, 0, 0]
or
f.fcntl Fcntl:F_SETLKW, { :l_type => Fcntl:F_WRLK }
Yes, I like the Hash one but requires modifying io.c with potentially
unportable code to support.
If we use non-String, maybe just call fcntl(2) inside ext/fcntl/fcntl.c
internally and forget about IO#fcntl in io.c entirely:
Fcntl::Flock[:WRLCK, :SET, 0, 0].lock(io)
Fcntl::Flock[:WRLCK, :SET, 0, 0].try_lock(io)
Fcntl::Flock[:SET, 0, 0].unlock(io)
Or even:
Fcntl.lock(io, :WRLCK, :SET, 0, 0)
Fcntl.try_lock(io, :WRLCK, :SET, 0, 0)
Fcntl.unlock(io, :SET, 0, 0)
Fcntl.getlock(io, :RDLCK, :SET, 0, 0) -> Fcntl::Flock object
That would allow us to do something stateful like:
Fcntl.synchronize(io, :WRLCK, :SET, 0, 0) do
# ...
end
I dislike all caps, even, taking hints from pthread_rwlock_*:
Fcntl.rdlock(io, :set, 0, 0)
Fcntl.tryrdlock(io, :set, 0, 0)
Fcntl.wrlock(io, :set, 0, 0)
Fcntl.trywrlock(io, :set, 0, 0)
Fcntl.unlock(io, :set, 0, 0)
Fcntl.read_synchronize(io, :set, 0, 0) do
# ...
end
Fcntl.synchronize(io, :set, 0, 0) do
# ...
end
But, of cource, I'm not against if matz ack yours. So I recommend you
describe the detailed interface to matz instead only just attached a patch.
It's best practice to persuade very busy person. :)
Thanks again for the feedback. So many ways to do this interface,
but just anything but Array#pack sounds good to me :)
--
Eric Wong
=end
Updated by normalperson (Eric Wong) over 13 years ago
=begin
Eric Wong normalperson@yhbt.net wrote:
KOSAKI Motohiro kosaki.motohiro@gmail.com wrote:
Umm..
I don't like its interface so much. your flock object don't mange any lock
state. it's merely wrapper of argument of fcntl. your interface mean we need
two line every lock operation. eg.That would allow us to do something stateful like:
Fcntl.synchronize(io, :WRLCK, :SET, 0, 0) do
...¶
end
Following up, I went with something along these lines here.
http://redmine.ruby-lang.org/issues/4464
http://redmine.ruby-lang.org/attachments/1540/0001-add-Fcntl-Lock-object-for-easier-use-of-POSIX-file-l.patch
Simple use case to lock the whole file is just:
Fcntl::Lock.synchronize(file) do
# ...
end
--
Eric Wong
=end
Updated by kosaki (Motohiro KOSAKI) over 13 years ago
=begin
Issue #4463 has been reported by Eric Wong.
Bug #4463: [PATCH] release GVL for fcntl() for operations that may block
http://redmine.ruby-lang.org/issues/4463Author: Eric Wong
Status: Open
Priority: Normal
Assignee:
Category: core
Target version: 1.9.x
ruby -v: ruby 1.9.3dev (2011-03-03 trunk 31011) [x86_64-linux]Users of F_SETLKW may block the entire VM via IO#fcntl,
release the GVL so other operations may continue.
Yeah.
It looks reasonable request. :)
=end
Updated by kosaki (Motohiro KOSAKI) over 13 years ago
=begin
Hi
2011/3/3 KOSAKI Motohiro kosaki.motohiro@gmail.com:
Issue #4463 has been reported by Eric Wong.
Bug #4463: [PATCH] release GVL for fcntl() for operations that may block
http://redmine.ruby-lang.org/issues/4463Author: Eric Wong
Status: Open
Priority: Normal
Assignee:
Category: core
Target version: 1.9.x
ruby -v: ruby 1.9.3dev (2011-03-03 trunk 31011) [x86_64-linux]Users of F_SETLKW may block the entire VM via IO#fcntl,
release the GVL so other operations may continue.Yeah.
It looks reasonable request. :)
Hi
I've commited slightly modified version today (r31025).
The difference is,
- All IO.fcntl() and IO.iocntl() relese GVL instead only SETLCKW. because,
A) if a user are using network filesystem, almost all fcntl need network
communication. iow, they can be blocked.
B) We are sure ioctl() has similar issue. But, we don't have any knowledge
which ioctl can be blocked. It is strongly dependend a
platform and a device. - Added small test. It is based on your Fcntl::Flock patch.
Thanks.
=end
Updated by normalperson (Eric Wong) over 13 years ago
=begin
KOSAKI Motohiro kosaki.motohiro@gmail.com wrote:
Hi
I've commited slightly modified version today (r31025).
The difference is,
- All IO.fcntl() and IO.iocntl() relese GVL instead only SETLCKW. because,
A) if a user are using network filesystem, almost all fcntl need network
communication. iow, they can be blocked.
B) We are sure ioctl() has similar issue. But, we don't have any knowledge
which ioctl can be blocked. It is strongly dependend a
platform and a device.
Agreed on both points.
- Added small test. It is based on your Fcntl::Flock patch.
Any chance of that patch making it into trunk? I'd be happy to make
any changes/improvements necessary (+docs, too). Thanks again.
--
Eric Wong
=end
Updated by kosaki (Motohiro KOSAKI) over 13 years ago
=begin
Hi
I've commited slightly modified version today (r31025).
The difference is,
- All IO.fcntl() and IO.iocntl() relese GVL instead only SETLCKW. because,
  A) if a user are using network filesystem, almost all fcntl need network
    communication. iow, they can be blocked.
  B) We are sure ioctl() has similar issue. But, we don't have any knowledge
    which ioctl can be blocked. It is strongly dependend a
platform and a device.Agreed on both points.
thank you.
- Added small test. It is based on your Fcntl::Flock patch.
Any chance of that patch making it into trunk? Â I'd be happy to make
any changes/improvements necessary (+docs, too). Â Thanks again.
Umm..
I don't like its interface so much. your flock object don't mange any lock
state. it's merely wrapper of argument of fcntl. your interface mean we need
two line every lock operation. eg.
lock
=end
Updated by normalperson (Eric Wong) over 13 years ago
=begin
KOSAKI Motohiro kosaki.motohiro@gmail.com wrote:
Umm..
I don't like its interface so much. your flock object don't mange any lock
state. it's merely wrapper of argument of fcntl. your interface mean we need
two line every lock operation. eg.lock = Fcntl::Flock.new Fcntl::F_WRLCK f.fcntl Fcntl::F_SETLKW, lock
I agree it's currently too verbose.
I tried to keep io.c the same so I used a String subclass. Maybe I
should just modify teach io.c to deal with Hash/Array arguments? I do
worry about placing more burden on io.c for portability reasons, though
POSIX file locks might be very common by now...
To shorten interface, maybe Fcntl::Flock[] can return an array for splat
and take symbol args (like new Socket):
f.fcntl *Fcntl::Flock[:F_SETLKW, :F_WRLCK, :SEEK_SET, 0, 0]
Or maybe even:
f.fcntl *Fcntl::Flock[:SETLKW, :WRLCK, :SET, 0, 0]
but I personally prefer array or hash capsulation. e.g
f.fcntl Fcntl:F_SETLKW, [Fcntl:F_WRLK, SEEK_SET, 0, 0]
or
f.fcntl Fcntl:F_SETLKW, { :l_type => Fcntl:F_WRLK }
Yes, I like the Hash one but requires modifying io.c with potentially
unportable code to support.
If we use non-String, maybe just call fcntl(2) inside ext/fcntl/fcntl.c
internally and forget about IO#fcntl in io.c entirely:
Fcntl::Flock[:WRLCK, :SET, 0, 0].lock(io)
Fcntl::Flock[:WRLCK, :SET, 0, 0].try_lock(io)
Fcntl::Flock[:SET, 0, 0].unlock(io)
Or even:
Fcntl.lock(io, :WRLCK, :SET, 0, 0)
Fcntl.try_lock(io, :WRLCK, :SET, 0, 0)
Fcntl.unlock(io, :SET, 0, 0)
Fcntl.getlock(io, :RDLCK, :SET, 0, 0) -> Fcntl::Flock object
That would allow us to do something stateful like:
Fcntl.synchronize(io, :WRLCK, :SET, 0, 0) do
# ...
end
I dislike all caps, even, taking hints from pthread_rwlock_*:
Fcntl.rdlock(io, :set, 0, 0)
Fcntl.tryrdlock(io, :set, 0, 0)
Fcntl.wrlock(io, :set, 0, 0)
Fcntl.trywrlock(io, :set, 0, 0)
Fcntl.unlock(io, :set, 0, 0)
Fcntl.read_synchronize(io, :set, 0, 0) do
# ...
end
Fcntl.synchronize(io, :set, 0, 0) do
# ...
end
But, of cource, I'm not against if matz ack yours. So I recommend you
describe the detailed interface to matz instead only just attached a patch.
It's best practice to persuade very busy person. :)
Thanks again for the feedback. So many ways to do this interface,
but just anything but Array#pack sounds good to me :)
--
Eric Wong
=end
Updated by normalperson (Eric Wong) over 13 years ago
=begin
Eric Wong normalperson@yhbt.net wrote:
KOSAKI Motohiro kosaki.motohiro@gmail.com wrote:
Umm..
I don't like its interface so much. your flock object don't mange any lock
state. it's merely wrapper of argument of fcntl. your interface mean we need
two line every lock operation. eg.That would allow us to do something stateful like:
Fcntl.synchronize(io, :WRLCK, :SET, 0, 0) do
...¶
end
Following up, I went with something along these lines here.
http://redmine.ruby-lang.org/issues/4464
http://redmine.ruby-lang.org/attachments/1540/0001-add-Fcntl-Lock-object-for-easier-use-of-POSIX-file-l.patch
Simple use case to lock the whole file is just:
Fcntl::Lock.synchronize(file) do
# ...
end
--
Eric Wong
=end