Permalink
Browse files

Fix for JRUBY-4747: read_nonblock error with couchrest

Looks like the missing logic for us was that when defining Errno classes we're supposed to reuse the same class for the same value. On the platform I tested, EAGAIN and EWOULDBLOCK are the same value, and so the rescue EWOULDBLOCK in couchrest rescues EAGAIN too.
  • Loading branch information...
1 parent c248e3a commit bdd6889270fa58006432295954f891e966dedcbc @headius headius committed Apr 26, 2010
Showing with 12 additions and 3 deletions.
  1. +12 −3 src/org/jruby/Ruby.java
View
@@ -1378,6 +1378,10 @@ private void initErrno() {
if (profile.allowModule("Errno")) {
errnoModule = defineModule("Errno");
try {
+ // define EAGAIN now, so that future EWOULDBLOCK will alias to it
+ // see MRI's error.c and its explicit ordering of Errno definitions.
+ createSysErr(Errno.EAGAIN.value(), Errno.EAGAIN.name());
+
for (Errno e : Errno.values()) {
Constant c = (Constant) e;
if (Character.isUpperCase(c.name().charAt(0))) {
@@ -1401,9 +1405,14 @@ private void initErrno() {
**/
private void createSysErr(int i, String name) {
if(profile.allowClass(name)) {
- RubyClass errno = getErrno().defineClassUnder(name, systemCallError, systemCallError.getAllocator());
- errnos.put(i, errno);
- errno.defineConstant("Errno", newFixnum(i));
+ if (errnos.get(i) == null) {
+ RubyClass errno = getErrno().defineClassUnder(name, systemCallError, systemCallError.getAllocator());
+ errnos.put(i, errno);
+ errno.defineConstant("Errno", newFixnum(i));
+ } else {
+ // already defined a class for this errno, reuse it (JRUBY-4747)
+ getErrno().setConstant(name, errnos.get(i));
+ }
}
}

0 comments on commit bdd6889

Please sign in to comment.