dadv: (chuck)
[personal profile] dadv

perl-threaded-5.14.4 (собран с useithreads=define, usemultiplicity=define).

Код такого вида:

#!/usr/bin/perl

use threads;
use threads::shared;
use strict;
use warnings;

our $db :shared;

sub func() {
  my $new;
  ... # формируем новые данные
  {   # пытаемся обновить $db, удерживая блокировку
    lock($db);
    $db = $new;
    $new = undef;
  }
}

Такой код проходит все проверки синтаксиса, но во время работы нить, выполняющая func() второй раз, аварийно завершает работу на строке $db = $new lock($db) с диагностикой panic: MUTEX_LOCK (22) [shared.xs:200].

Ошибка 22 это EINVAL. В потрохах perl есть dist/threads-shared/shared.xs и в нём функция recursive_lock_release(pTHX_ recursive_lock_t *lock), которая зовёт MUTEX_LOCK(&lock->mutex) - макрос, который выкидывает этот panic, если неуспешно завершается системная функция pthread_mutex_lock() из POSIX Threads Library (libpthread, -lpthread). А она возвращает EINVAL, если переданный мутекс равен THR_MUTEX_DESTROYED.

Выходит, переписывание скаляра новым значением при удерживании блокировки разрушает мутекс. Решение было очевидным: завести под блокировку отдельный скаляр $dblock и при разграничении доступа к $db лочить $dblock.

Update: test-case.

Date: 2013-11-15 07:36 (UTC)
From: [identity profile] http://users.livejournal.com/_slw/
This is perl 5, version 16, subversion 2 (v5.16.2) built for amd64-freebsd-thread-multi

_OPTIONS_READ=perl-threaded-5.16.2_1
_FILE_COMPLETE_OPTIONS_LIST=DEBUG GDBM MULTIPLICITY PERL_64BITINT PERL_MALLOC PTHREAD SITECUSTOMIZE THREADS USE_PERL
OPTIONS_FILE_UNSET+=DEBUG
OPTIONS_FILE_UNSET+=GDBM
OPTIONS_FILE_SET+=MULTIPLICITY
OPTIONS_FILE_SET+=PERL_64BITINT
OPTIONS_FILE_UNSET+=PERL_MALLOC
OPTIONS_FILE_SET+=PTHREAD
OPTIONS_FILE_UNSET+=SITECUSTOMIZE
OPTIONS_FILE_SET+=THREADS
OPTIONS_FILE_SET+=USE_PERL

ошибок не кидает

Date: 2013-11-15 08:06 (UTC)
From: [identity profile] dadv.livejournal.com
А ты реально создавал больше одного треда, детачил их, прогонял func() два раза?

Date: 2013-11-15 09:08 (UTC)
From: [identity profile] http://users.livejournal.com/_slw/
я запустил твой пример

Date: 2013-11-15 09:20 (UTC)
From: [identity profile] dadv.livejournal.com
Это почти "псевдокод", в нём для реального воспроизведения баги кучи всего не хватает.

Date: 2013-11-15 12:21 (UTC)
From: [identity profile] http://users.livejournal.com/_slw/
так напиши что бы хватало

Date: 2013-11-16 00:14 (UTC)
From: [identity profile] dadv.livejournal.com
http://www.grosbein.net/files/panic.pl

Выдаёт:

func: new iteration started
func: iteration finished
func: new iteration started
Thread 1 terminated abnormally: panic: MUTEX_LOCK (22) [shared.xs:200] at ./panic.pl line 21.

Date: 2013-11-16 00:34 (UTC)
From: [identity profile] dadv.livejournal.com
Если даже $new сделать разделяемой, ничего не меняется.

--- panic.pl    2013-11-16 07:11:49.000000000 +0700
+++ panic2.pl   2013-11-16 07:31:53.000000000 +0700
@@ -8,9 +8,9 @@
 $|=1;
 
 our $db :shared;
+our $new :shared;
 
 sub func() {
-  my $new;
 
   while (1) {
     print STDERR "func: new iteration started\n";

Date: 2013-11-15 16:12 (UTC)
From: [identity profile] bufmgr.livejournal.com
Этот глючный перл из freebsd.Много чего в либах не работает так, как заявлено.Можно копать если времени не жалко.

Date: 2013-11-15 22:19 (UTC)
From: [identity profile] dadv.livejournal.com
perl 5.14 не является частью FreeBSD и никогда не был. Как и любой другой сторонний софт, он установлен отдельно.

Date: 2013-11-16 00:38 (UTC)
From: [identity profile] dadv.livejournal.com
И зачем, скажи на милость, плодить виртуалов?

Date: 2013-11-16 07:44 (UTC)
From: [identity profile] ospf-ripe.livejournal.com
5.14 это очень старый perl и вряд ли кому то интересно искать там ошибки поскольку они уже могут быть пофикшены. Мы используем большей частью 5.16 и переходим 5.18
Edited Date: 2013-11-16 07:45 (UTC)

Date: 2013-11-16 08:53 (UTC)
From: [identity profile] dadv.livejournal.com
Тредовый используете?

Date: 2013-11-16 11:41 (UTC)
From: [identity profile] ospf-ripe.livejournal.com
Нет, таких задач нет, где нужен тредовый.
usemultiplicity использую в одном месте, где нужен perl встроенный в nginx, но там код простейший...

Profile

dadv: (Default)
Choose your future

July 2024

M T W T F S S
12 34567
891011121314
15161718192021
22232425262728
293031    

Tags

Style Credit

Powered by Dreamwidth Studios