xref: /onnv-gate/usr/src/lib/libast/common/sfio/sfstack.c (revision 12068:08a39a083754)
14887Schin /***********************************************************************
24887Schin *                                                                      *
34887Schin *               This software is part of the ast package               *
4*12068SRoger.Faulkner@Oracle.COM *          Copyright (c) 1985-2010 AT&T Intellectual Property          *
54887Schin *                      and is licensed under the                       *
64887Schin *                  Common Public License, Version 1.0                  *
78462SApril.Chin@Sun.COM *                    by AT&T Intellectual Property                     *
84887Schin *                                                                      *
94887Schin *                A copy of the License is available at                 *
104887Schin *            http://www.opensource.org/licenses/cpl1.0.txt             *
114887Schin *         (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9)         *
124887Schin *                                                                      *
134887Schin *              Information and Software Systems Research               *
144887Schin *                            AT&T Research                             *
154887Schin *                           Florham Park NJ                            *
164887Schin *                                                                      *
174887Schin *                 Glenn Fowler <gsf@research.att.com>                  *
184887Schin *                  David Korn <dgk@research.att.com>                   *
194887Schin *                   Phong Vo <kpv@research.att.com>                    *
204887Schin *                                                                      *
214887Schin ***********************************************************************/
224887Schin #include	"sfhdr.h"
234887Schin 
244887Schin 
254887Schin /*	Push/pop streams
264887Schin **
274887Schin **	Written by Kiem-Phong Vo.
284887Schin */
294887Schin 
304887Schin #define STKMTXLOCK(f1,f2) \
314887Schin 	{ if(f1) SFMTXLOCK(f1); \
324887Schin 	  if(f2) SFMTXLOCK(f2); \
334887Schin 	}
344887Schin #define STKMTXRETURN(f1,f2,rv) \
354887Schin 	{ if(f1) SFMTXUNLOCK(f1); \
364887Schin 	  if(f2) SFMTXUNLOCK(f2); \
374887Schin 	  return(rv); \
384887Schin 	}
394887Schin 
404887Schin #if __STD_C
sfstack(Sfio_t * f1,Sfio_t * f2)414887Schin Sfio_t* sfstack(Sfio_t* f1, Sfio_t* f2)
424887Schin #else
434887Schin Sfio_t* sfstack(f1,f2)
444887Schin Sfio_t*	f1;	/* base of stack	*/
454887Schin Sfio_t*	f2;	/* top of stack	*/
464887Schin #endif
474887Schin {
484887Schin 	reg int		n;
494887Schin 	reg Sfio_t*	rf;
504887Schin 	reg Sfrsrv_t*	rsrv;
514887Schin 	reg Void_t*	mtx;
524887Schin 
534887Schin 	STKMTXLOCK(f1,f2);
544887Schin 
554887Schin 	if(f1 && (f1->mode&SF_RDWR) != f1->mode && _sfmode(f1,0,0) < 0)
564887Schin 		STKMTXRETURN(f1,f2, NIL(Sfio_t*));
574887Schin 	if(f2 && (f2->mode&SF_RDWR) != f2->mode && _sfmode(f2,0,0) < 0)
584887Schin 		STKMTXRETURN(f1,f2, NIL(Sfio_t*));
594887Schin 	if(!f1)
604887Schin 		STKMTXRETURN(f1,f2, f2);
614887Schin 
624887Schin 	/* give access to other internal functions */
634887Schin 	_Sfstack = sfstack;
644887Schin 
654887Schin 	if(f2 == SF_POPSTACK)
664887Schin 	{	if(!(f2 = f1->push))
674887Schin 			STKMTXRETURN(f1,f2, NIL(Sfio_t*));
684887Schin 		f2->mode &= ~SF_PUSH;
694887Schin 	}
704887Schin 	else
714887Schin 	{	if(f2->push)
724887Schin 			STKMTXRETURN(f1,f2, NIL(Sfio_t*));
734887Schin 		if(f1->pool && f1->pool != &_Sfpool && f1->pool != f2->pool &&
744887Schin 		   f1 == f1->pool->sf[0])
754887Schin 		{	/* get something else to pool front since f1 will be locked */
764887Schin 			for(n = 1; n < f1->pool->n_sf; ++n)
774887Schin 			{	if(SFFROZEN(f1->pool->sf[n]) )
784887Schin 					continue;
794887Schin 				(*_Sfpmove)(f1->pool->sf[n],0);
804887Schin 				break;
814887Schin 			}
824887Schin 		}
834887Schin 	}
844887Schin 
854887Schin 	if(f2->pool && f2->pool != &_Sfpool && f2 != f2->pool->sf[0])
864887Schin 		(*_Sfpmove)(f2,0);
874887Schin 
884887Schin 	/* swap streams */
894887Schin 	sfswap(f1,f2);
904887Schin 
914887Schin 	/* but the reserved buffer and mutex must remain the same */
924887Schin 	rsrv = f1->rsrv; f1->rsrv = f2->rsrv; f2->rsrv = rsrv;
934887Schin 	mtx = f1->mutex; f1->mutex = f2->mutex; f2->mutex = mtx;
944887Schin 
954887Schin 	SFLOCK(f1,0);
964887Schin 	SFLOCK(f2,0);
974887Schin 
984887Schin 	if(f2->push != f2)
994887Schin 	{	/* freeze the pushed stream */
1004887Schin 		f2->mode |= SF_PUSH;
1014887Schin 		f1->push = f2;
1024887Schin 		rf = f1;
1034887Schin 	}
1044887Schin 	else
1054887Schin 	{	/* unfreeze the just exposed stream */
1064887Schin 		f1->mode &= ~SF_PUSH;
1074887Schin 		f2->push = NIL(Sfio_t*);
1084887Schin 		rf = f2;
1094887Schin 	}
1104887Schin 
1114887Schin 	SFOPEN(f1,0);
1124887Schin 	SFOPEN(f2,0);
1134887Schin 
1144887Schin 	STKMTXRETURN(f1,f2, rf);
1154887Schin }
116