ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/Coro/Coro/State.xs
(Generate patch)

Comparing Coro/Coro/State.xs (file contents):
Revision 1.281 by root, Sun Nov 16 10:12:38 2008 UTC vs.
Revision 1.282 by root, Sun Nov 16 10:33:08 2008 UTC

1987} 1987}
1988 1988
1989/*****************************************************************************/ 1989/*****************************************************************************/
1990 1990
1991static void 1991static void
1992coro_semaphore_adjust (pTHX_ AV *av, int adjust) 1992coro_semaphore_adjust (pTHX_ AV *av, IV adjust)
1993{ 1993{
1994 SV *count_sv = AvARRAY (av)[0]; 1994 SV *count_sv = AvARRAY (av)[0];
1995 IV count = SvIVX (count_sv); 1995 IV count = SvIVX (count_sv);
1996 1996
1997 count += adjust; 1997 count += adjust;
1998 SvIVX (count_sv) = count; 1998 SvIVX (count_sv) = count;
1999 1999
2000 /* now wake up as many waiters as possible */ 2000 /* now wake up as many waiters as are expected to lock */
2001 while (count > 0 && AvFILLp (av) >= count) 2001 while (count > 0 && AvFILLp (av) > 0)
2002 { 2002 {
2003 SV *cb; 2003 SV *cb;
2004 2004
2005 /* swap first two elements so we can shift a waiter */ 2005 /* swap first two elements so we can shift a waiter */
2006 AvARRAY (av)[0] = AvARRAY (av)[1]; 2006 AvARRAY (av)[0] = AvARRAY (av)[1];
2019} 2019}
2020 2020
2021static void 2021static void
2022coro_semaphore_on_destroy (pTHX_ struct coro *coro) 2022coro_semaphore_on_destroy (pTHX_ struct coro *coro)
2023{ 2023{
2024 /* call $sem->adjust (0) to possibly wake up some waiters */ 2024 /* call $sem->adjust (0) to possibly wake up some other waiters */
2025 coro_semaphore_adjust (aTHX_ (AV *)coro->slf_frame.data, 0); 2025 coro_semaphore_adjust (aTHX_ (AV *)coro->slf_frame.data, 0);
2026} 2026}
2027 2027
2028static int 2028static int
2029slf_check_semaphore_down (pTHX_ struct CoroSLF *frame) 2029slf_check_semaphore_down (pTHX_ struct CoroSLF *frame)
2060 2060
2061 if (SvIVX (AvARRAY (av)[0]) > 0) 2061 if (SvIVX (AvARRAY (av)[0]) > 0)
2062 { 2062 {
2063 frame->data = (void *)av; 2063 frame->data = (void *)av;
2064 frame->prepare = prepare_nop; 2064 frame->prepare = prepare_nop;
2065 SvSTATE_current->on_destroy = coro_semaphore_on_destroy;
2065 } 2066 }
2066 else 2067 else
2067 { 2068 {
2068 av_push (av, SvREFCNT_inc (SvRV (coro_current))); 2069 av_push (av, SvREFCNT_inc (SvRV (coro_current)));
2069 2070
2070 frame->data = (void *)sv_2mortal (SvREFCNT_inc ((SV *)av)); 2071 frame->data = (void *)sv_2mortal (SvREFCNT_inc ((SV *)av));
2071 frame->prepare = prepare_schedule; 2072 frame->prepare = prepare_schedule;
2072 2073
2073 /* to avoid race conditions when a woken-up coro gets terminated */ 2074 /* to avoid race conditions when a woken-up coro gets terminated */
2074 /* we arrange for a temporary on_destroy that calls adjust (0) */ 2075 /* we arrange for a temporary on_destroy that calls adjust (0) */
2076 assert (!SvSTATE_current->on_destroy);//D
2075 SvSTATE_current->on_destroy = coro_semaphore_on_destroy; 2077 SvSTATE_current->on_destroy = coro_semaphore_on_destroy;
2076 } 2078 }
2077 2079
2078 frame->check = slf_check_semaphore_down; 2080 frame->check = slf_check_semaphore_down;
2079 2081

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines