/*
 * if with pthread
 */
#include "ystring.h"
#include "log.h"
#include "sysconf.h"
#if defined(__cplusplus) && !defined(DG_WITH_PTHREAD) && !defined(__CYGWIN__)
#else
#include <pthread.h>
#endif
int Uname(PVStr(un));

const char *WithMutex = "pthread";
typedef struct {
	int xcs_ok;
	const char *xcs_wh;
	pthread_mutex_t xcs_cs;
} XCS;
int setupCSC(const char *wh,void **acs,int asz){
	XCS *xcs = (XCS*)acs;
	IStr(uname,128);

	if( asz < sizeof(XCS) ){
		Uname(AVStr(uname));
		fprintf(stderr,"----setupCSC: too small %d/%d (%s)\n",
			asz,sizeof(XCS),uname);
		return -1;
	}
	if( xcs->xcs_ok ){
		return 0;
	}
	xcs->xcs_ok = 1;
	xcs->xcs_wh = wh;
	pthread_mutex_init(&xcs->xcs_cs,0);
        return 0;
}   
static int ng,ok;
#undef fprintf
int enterCSCX(void **acs,int timeout){
	XCS *xcs = (XCS*)acs;
	int cum,rem,to1;

	for( cum = 0; cum <= timeout; cum += to1 ){
		if( pthread_mutex_trylock(&xcs->xcs_cs) == 0 ){
			ok++;
			/*
			fprintf(stderr,"-- %4X CSC %X OK %d/%d\n",
				TID,acs,cum,timeout);
			*/
			return 0;
		}
		rem = timeout - cum;
		if( rem <= 0 ){
			break;
		}
		if(   10 <= rem && cum <=  100 ) to1 =  10; else
		if(  100 <= rem && cum <= 1000 ) to1 = 100; else
		if(  500 <= rem && cum <= 5000 ) to1 = 500; else
		if( 1000 <= rem )
			to1 = 1000;
		else	to1 = rem;
		usleep(to1*1000);
	}
	ng++;
	if( xcs && strheadstrX(xcs->xcs_wh,"ThreadServers",0) == 0 )
	fprintf(stderr,"-- %4X CSC %X NG %s %d/%d\n",TID,acs,xcs->xcs_wh,
		cum,timeout);
	return -1;
}
int enterCSC(void **acs){
	XCS *xcs = (XCS*)acs;
	IStr(uname,128);
	if( xcs->xcs_ok <= 0 ){
		fprintf(stderr,"----enterCSC... not init. yet\n");
		return -1;
	}
	if( pthread_mutex_trylock(&xcs->xcs_cs) == 0 ){
		ok++;
		return 0;
	}
	ng++;
	Uname(AVStr(uname));
	/*
	fprintf(stderr,"----enterCSC... %d:%d (%s)\n",ok,ng,uname);
	*/
	if( pthread_mutex_lock(&xcs->xcs_cs) == 0 )
		return 0;
        return -1;
}
int leaveCSC(void **acs){
	XCS *xcs = (XCS*)acs;
	if( pthread_mutex_unlock(&xcs->xcs_cs) == 0 )
		return 0;
	return -1;
}
