[#47562] [Backport 200 - Backport #8716][Open] segmation fault 正規表現で大量のグループを利用時 — "taka-yoshi (taka-yoshi taka)" <smokeonthewater222@...>

15 messages 2013/08/01

[#47569] [ruby-trunk - Feature #8726][Open] Class#source_location — "takiuchi (Genki Takiuchi)" <genki@...21g.com>

14 messages 2013/08/03

[#47663] Re: [ruby-core:56878] [ruby-trunk - misc #8835][Open] Introducing a semantic versioning scheme and branching policy — "Akinori MUSHA" <knu@...>

At Fri, 30 Aug 2013 21:49:34 +0900,

6 messages 2013/08/30

[ruby-dev:47655] Re: [ruby-trunk - Bug #8810][Open] SolarisでGDBM.open内で処理がブロックしたらTimeout.timeout が効かない

From: KOSAKI Motohiro <kosaki.motohiro@...>
Date: 2013-08-23 23:24:29 UTC
List: ruby-dev #47655
2013/8/22 ngoto (Naohisa Goto) <ngotogenome@gmail.com>:
>
> Issue #8810 has been reported by ngoto (Naohisa Goto).
>
> ----------------------------------------
> Bug #8810: SolarisでGDBM.open内で処理がブロックしたらTimeout.timeout が効かない
> https://bugs.ruby-lang.org/issues/8810
>
> Author: ngoto (Naohisa Goto)
> Status: Open
> Priority: Normal
> Assignee:
> Category: ext
> Target version:
> ruby -v: -
> Backport: 1.9.3: UNKNOWN, 2.0.0: UNKNOWN
>
>
> GDBM.open内で処理がブロックした場合にTimeout.timeoutが効きません。
>
> 再現方法は、Solarisにて、以下のようにGDBMをオープンしたままにして、
>
>  $ ruby -r gdbm -e 'db = GDBM.open("/var/tmp/tmpdb"); gets'
>
> 同一マシンで別のシェルで
>
>  $ ruby -r gdbm -r timeout -e 'Timeout.timeout(5) { db = GDBM.open("/var/tmp/tmpdb") }'
>
> を実行しても、タイムアウトすることなく後者のGDBM.openがブロックし続けて終わりません。
>
> Solarisだけでなく、Linux上にて、以下のように無理やりflockを使わないようconfigureしてmakeしたlibgdbm.soを使用した場合でも同様に再現しました。

ちらっと見たのですが、これはgdbmを直さないとどうしようもないような
以下コメント付きソースの抜粋。

int
_gdbm_lock_file (GDBM_FILE dbf)
{
#if HAVE_FCNTL_LOCK
  struct flock fl;
#endif
  int lock_val = -1;

#if HAVE_FLOCK  // 最初にflockを試す
  if (dbf->read_write == GDBM_READER)
    lock_val = flock (dbf->desc, LOCK_SH + LOCK_NB); // この時はLOCK_NB使う
  else
    lock_val = flock (dbf->desc, LOCK_EX + LOCK_NB);

  if ((lock_val == -1) && (errno == EWOULDBLOCK))
    {
      dbf->lock_type = LOCKING_NONE;
      return lock_val;
    }
  else if (lock_val != -1)
    {
      dbf->lock_type = LOCKING_FLOCK;
      return lock_val;
    }
#endif

// 次に lockf ためす
#if HAVE_LOCKF
  /* Mask doesn't matter for lockf. */
  lock_val = lockf (dbf->desc, F_LOCK, (off_t)0L); // なぜか F_TLOCK つけない
  if ((lock_val == -1) && (errno == EDEADLK))
    {
      dbf->lock_type = LOCKING_NONE;
      return lock_val;
    }
  else if (lock_val != -1)
    {
      dbf->lock_type = LOCKING_LOCKF;
      return lock_val;
    }
#endif

// 最後に fcntl ためす
#if HAVE_FCNTL_LOCK
  /* If we're still here, try fcntl. */
  if (dbf->read_write == GDBM_READER)
    fl.l_type = F_RDLCK;
  else
    fl.l_type = F_WRLCK;
  fl.l_whence = SEEK_SET;
  fl.l_start = fl.l_len = (off_t)0L;
  lock_val = fcntl (dbf->desc, F_SETLK, &fl); // こんどはF_SETLKなので待たない

  if (lock_val != -1)
    dbf->lock_type = LOCKING_FCNTL;
#endif

  if (lock_val == -1)
    dbf->lock_type = LOCKING_NONE;
  return lock_val;
}

In This Thread

Prev Next