/***********************************************************************
* *
* This software is part of the ast package *
* Copyright (c) 1985-2011 AT&T Intellectual Property *
* and is licensed under the *
* Eclipse Public License, Version 1.0 *
* by AT&T Intellectual Property *
* *
* A copy of the License is available at *
* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
* *
* Information and Software Systems Research *
* AT&T Research *
* Florham Park NJ *
* *
* Glenn Fowler <gsf@research.att.com> *
* David Korn <dgk@research.att.com> *
* Phong Vo <kpv@research.att.com> *
* *
***********************************************************************/
#include "sfhdr.h"
/* Management of pools of streams.
** If pf is not nil, f is pooled with pf and f becomes current;
** otherwise, f is isolated from its pool. flag can be one of
** 0 or SF_SHARE.
**
** Written by Kiem-Phong Vo.
*/
/* Note that we do not free the space for a pool once it is allocated.
** This is to prevent memory faults in calls such as sfsync(NULL) that walk the pool
** link list and during such walks may free up streams&pools. Free pools will be
** reused in newpool().
*/
#if __STD_C
#else
static int delpool(p)
#endif
{
POOLMTXENTER(p);
POOLMTXRETURN(p,0);
}
#if __STD_C
#else
#endif
{
/* look to see if there is a free pool */
{ p->mode = 0;
break;
}
}
if(!p)
{ POOLMTXLOCK(last);
{ POOLMTXUNLOCK(last);
}
p->mode = 0;
p->n_sf = 0;
}
POOLMTXENTER(p);
POOLMTXRETURN(p,p);
}
/* move a stream to head */
#if __STD_C
#else
static int _sfphead(p, f, n)
Sfpool_t* p; /* the pool */
Sfio_t* f; /* the stream */
int n; /* current position in pool */
#endif
{
POOLMTXENTER(p);
if(n == 0)
POOLMTXRETURN(p,0);
POOLMTXRETURN(p,-1);
rv = -1;
goto done;
}
else /* shared pool of write-streams, data can be moved among streams */
goto done;
k = 0;
else /* try to write out amount exceeding f's capacity */
v -= k;
else /* write failed, recover buffer then quit */
{ if(w > 0)
{ v -= w;
}
goto done;
}
}
/* move data from head to f */
}
p->sf[0] = f;
rv = 0;
done:
POOLMTXRETURN(p,rv);
}
/* delete a stream from its pool */
#if __STD_C
#else
static int _sfpdelete(p, f, n)
Sfpool_t* p; /* the pool */
Sfio_t* f; /* the stream */
int n; /* position in pool */
#endif
{
POOLMTXENTER(p);
p->n_sf -= 1;
for(; n < p->n_sf; ++n)
{ if(p != &_Sfpool)
delpool(p);
goto done;
}
/* !_Sfpool, make sure head stream is an open stream */
for(n = 0; n < p->n_sf; ++n)
break;
if(n < p->n_sf && n > 0)
{ f = p->sf[n];
p->sf[0] = f;
}
/* head stream has SF_POOL off */
f = p->sf[0];
if(!SFFROZEN(f))
_SFOPEN(f);
/* if only one stream left, delete pool */
if(p->n_sf == 1 )
{ _sfpdelete(p,f,0);
_sfsetpool(f);
}
done:
POOLMTXRETURN(p,0);
}
#if __STD_C
#else
#endif
{
reg int n;
if(type > 0)
return _sfsetpool(f);
else
{ if(!(p = f->pool) )
return -1;
for(n = p->n_sf-1; n >= 0; --n)
if(p->sf[n] == f)
break;
if(n < 0)
return -1;
}
}
#if __STD_C
#else
#endif
{
int k;
Sfpool_t* p;
if(!f) /* return head of pool of pf regardless of lock states */
{ if(!pf)
return pf;
}
if(f) /* check for permissions */
{ SFMTXLOCK(f);
{ SFMTXUNLOCK(f);
}
}
if(pf)
{ if(f)
SFMTXUNLOCK(f);
}
}
/* f already in the same pool with pf */
{ if(f)
SFMTXUNLOCK(f);
if(pf)
return pf;
}
/* lock streams before internal manipulations */
SFLOCK(f,0);
if(pf)
if(!pf) /* deleting f from its current pool */
if(p->sf[k] != f) /* a stream != f represents the pool */
if(!pf) /* already isolated */
{ rv = f; /* just return self */
goto done;
}
goto done; /* can't delete */
goto done;
}
goto done;
goto done;
goto done;
}
goto done;
goto done;
goto done;
p->n_sf += 1;
}
f->pool = p; /* add f to pf's pool */
if(_sfsetpool(f) < 0)
goto done;
SFOPEN(f,0);
if(_sfpmove(f,0) < 0) /* make f head of pool */
goto done;
done:
if(f)
{ SFOPEN(f,0);
SFMTXUNLOCK(f);
}
if(pf)
}
return rv;
}