<?php
/*
 * framework-spider
 * util/LockProcess.class.php
 * 
 * CopyRight(C)Framework-Spider Developer Team. 2010. All Right Reserved. 
 * URL         : http://sourceforge.jp/projects/frameworkspider/
 * Mail        : frameworkspider-dev@lists.sourceforge.jp
 * Auther      : Masanori Nakashima
 * Modifier    : Masanori Nakashima
 * Last Updated: 2010.06.23
 * 
 */
define( "UTIL_LOCK_PROCESS_MAX_LOOP",	30 );
/**
 * ユーティリティ：プロセスロックを行うユーティリティオブジェクト
 * 
 * @package util ユーティリティパッケージ
 * @version 1.0.0
 * @copyright Copyright &copy; 2008, <m_nakashima@users.sourceforge.jp> http://sourceforge.jp/projects/shopformer/
 * @author  m.nakashima <m_nakashima@users.sourceforge.jp>
 * @since PHP 4.3
 */
class util_LockProcess {
	
	var $lock_name		= 'common';
	var $lock_file_name;
	
	/**
	 * コンストラクタ
	 */	
	function util_LockProcess($lock_name=null,$lock_dir_path=null){
		if( !is_null( $lock_name ) && strlen(trim($lock_name))) {
			$this->lock_name	= $lock_name;
			$this->lock_name
				= str_replace( DIRECTORY_SEPARATOR, '_S_', $this->lock_name );
			if( preg_match( '/\\:/', $this->lock_name ) ) {
				$this->lock_name	= str_replace( ':', '_C_', $this->lock_name );
			}
		}
		if( is_null( $lock_dir_path ) ) {
			$lock_dir_path		= DIR_PATH_LOCK;
		}
		$this->lock_file_name	= $lock_dir_path
			.DIRECTORY_SEPARATOR.".".$this->lock_name;
	}
	
	/**
	 * ロックを確認、開始します。
	 * @return 成功したらtrue / ロックに失敗したらfalse
	 */
	function lock(){
		// 現在ロックがかかっているか確認する
		if( $this->wait() ) {
			// ロックがかかっていないならロックディレクトリ作成
			mkdir( $this->lock_file_name, SPIDER_PERMITTION_DATA_FOLDER );
			chmod( $this->lock_file_name, SPIDER_PERMITTION_DATA_FOLDER );
			return true;
		} else {
			return false;
		}
	}
	
	/**
	 * 指定名のロックを解除します。
	 */
	function release(){
		if( is_dir( $this->lock_file_name ) ){
			rmdir( $this->lock_file_name );
		}
		return true;
	}
	/**
	 * ロックが解除されるまで待機します
	 */
	function wait() {
		$loop_count	= 0;
		while( true ) {
			$loop_count++;
			if( $loop_count > UTIL_LOCK_PROCESS_MAX_LOOP ){
				return false;
			} else if ( !is_dir( $this->lock_file_name ) ) {
				return true;
			} else if ( filemtime($this->lock_file_name) + 30 < time() ){
				$this->release();
				return true;
			} else {
				usleep(500);
				continue;
			}
		}
	}
}

?>