示例#1
0
void session::deserialize(string& buf, std::map<string, VBUF*>& attrs)
{
	attrs_clear(attrs);  // 先重置 session 前一次查询状态

	ACL_ARGV* tokens = acl_argv_split(buf.c_str(), "\t");
	ACL_ITER  iter;
	acl_foreach(iter, tokens)
	{
		char* ptr = (char*) iter.data;

		// 重复使用原来的内存区,因为 tokens 中已经存储了中间结果数据
		buf.clear();
		if (unescape(ptr, strlen(ptr), buf) == false)
		{
			logger_error("unescape error");
			continue;
		}
		ptr = buf.c_str();
		// 因为 acl::string 肯定能保证缓冲区数据的尾部有 \0,所以在用
		// strchr 时不必须担心越界问题,但 std::string 并不保证这样
		char* p1 = strchr(ptr, 1);
		if (p1 == NULL || *(p1 + 1) == 0)
			continue;
		*p1++ = 0;
		std::map<string, VBUF*>::iterator it = attrs.find(ptr);

		// xxx: 以防有重复的属性
		if (it != attrs.end())
			vbuf_free(it->second);
		// 将从后端取得数据属性都设为 TODO_SET
		attrs[ptr] = vbuf_new(p1, buf.length() - (p1 - buf.c_str()), TODO_SET);
	}
示例#2
0
void session::attrs_clear(std::map<string, VBUF*>& attrs)
{
	if (attrs.empty())
		return;

	std::map<string, VBUF*>::iterator it = attrs.begin();
	for (; it != attrs.end(); ++it)
		vbuf_free(it->second);
	attrs.clear();
}
示例#3
0
bool session::del(const char* name, bool delay /* = false */)
{
	if (delay)
	{
		std::map<string, VBUF*>::iterator it = attrs_cache_.find(name);
		if (it == attrs_cache_.end())
			attrs_cache_[name] = vbuf_new("", 0, TODO_DEL);
		else
			it->second->todo = TODO_DEL;
		dirty_ = true;
		return true;
	}

	// 直接操作后端 cache 服务器,删除属性字段

	string buf(256);
	if (get_data(sid_->buf, buf) == false)
		return true;

	deserialize(buf, attrs_);
	std::map<string, VBUF*>::iterator it = attrs_.find(name);
	if (it == attrs_.end())
		return false;

	// 先删除并释放对应的对象
	vbuf_free(it->second);
	attrs_.erase(it);

	// 如果 sid 中已经没有了数据,则应该将 sid 对象从 memcached 中删除
	if (attrs_.empty())
	{
		// 调用虚函数,删除该 sid 对应的缓存内容
		if (del_data(sid_->buf) == false)
		{
			logger_error("del sid(%s) error", sid_->buf);
			return false;
		}
		return true;
	}

	// 向 memcached 中重新添加剩余的数据

	serialize(attrs_, buf);
	attrs_clear(attrs_);

	if (set_data(sid_->buf, buf.c_str(), buf.length(), ttl_) == false)
	{
		logger_error("set cache error, sid(%s)", sid_->buf);
		return false;
	}
	return true;
}
示例#4
0
void
storageTask(
	void *param
)
{
	int ret;
	storageMsg_t msgData;
	storageMsg_t *msg = &msgData;
	unsigned int msg_prio;
	//int is_finish =0;
	printf("\nStorage thread enter ...\n\n");

	while (1) {
		ret = mq_receive(storageMsgQ, (char *) msg, sizeof(storageMsg_t), &msg_prio);
		if (ret < 0) {
			printf("[%s:%d], storage receive msg fail.\n", __FUNCTION__, __LINE__);
			continue;
		}

		//printf("receive storage msg %d, 0x%x\n", msg->cmd, msg->handle);
		if(msg->cmd == STORAGE_CMD_WRITE || msg->cmd == STORAGE_CMD_WRITE_AUDIO) {
			streamInfo_t *streamHandle = (streamInfo_t *) msg->handle;
			storageHandle_t *storageHandle = (storageHandle_t*) streamHandle->storageHandle;
			gpMuxPkt_t MuxPkt;
			
			int isAudio = (msg->cmd == STORAGE_CMD_WRITE_AUDIO) ? 1: 0;

			if (storageHandle && storageHandle->hdMux) {
				ret = 0;
				if (isAudio)
				{
					MuxPkt.data = (UINT8*)((audio_buffer_t*)(msg->buffer))->frame->pAddr;
					MuxPkt.size = msg->nBytes;
					MuxPkt.pts = msg->pts;//AUDIO_BUFFER_TIME;
					//printf("audio time =%d\n",msg->pts);
					if(storageHandle->hdMux)
						ret = g_save_Mux->pack(storageHandle->hdMux, &MuxPkt, GP_ES_TYPE_AUDIO);
						
					abuf_free((audio_buffer_t*)(msg->buffer));
				}
				else
				{
					IPC_Video_Frame_s* frame = ((video_buffer_t*)(msg->buffer))->frame;
					if (frame->thumb && storageHandle->hdMux)
					{
						MuxPkt.data = frame->thumb;
						MuxPkt.size = frame->thumb_size;
						ret = g_save_Mux->pack(storageHandle->hdMux, &MuxPkt, GP_ES_TYPE_THUMB);
					}
					MuxPkt.data = frame->pFrameAddr;
					MuxPkt.size = msg->nBytes;
					
					if (!storageHandle->time_lapse && (storageHandle->last_pts > 0) && (msg->pts > storageHandle->last_pts))
						MuxPkt.pts = msg->pts - storageHandle->last_pts;
					else
						MuxPkt.pts = 1000/storageHandle->framerate;
						
					if (MuxPkt.pts > 3600*1000) //avoid unexpected frame time 
					{
						printf("unexpected large frame time %u\n", MuxPkt.pts);
						MuxPkt.pts = 1000/storageHandle->framerate;
					}
					
					storageHandle->last_pts = msg->pts;
					MuxPkt.frameType = msg->frameType;
					if(storageHandle->hdMux)
						ret = g_save_Mux->pack(storageHandle->hdMux, &MuxPkt, GP_ES_TYPE_VIDEO);
						
					vbuf_free((video_buffer_t*)(msg->buffer));
				}
				
				if (ret != 0)
				{
					if (ret == MUX_MEM_FULL)
					{
						printf("[dvr] disk is full, stop recording.\n");
						streamHandle->status = STATUS_DISK_FULL;
					}
					else if (ret == MUX_FILE_SIZE_REACH)
					{
						printf("[dvr] reach maximum file size (2G), stop recording.\n");
						streamHandle->status = STATUS_FILE_SIZE_LIMIT;
					}
					else
					{
						printf("[dvr] unknown file error. stop recording.\n");
						streamHandle->status = STATUS_DISK_ERROR;
					}
					g_save_Mux->close(storageHandle->hdMux);
					storageHandle->hdMux = 0;
					if(storageHandle->file)
						fclose(storageHandle->file);
					free(storageHandle);
					streamHandle->storageHandle = NULL;
					sync();
				}
			}
			else
			{
				if (isAudio)
					abuf_free((audio_buffer_t*)(msg->buffer));
				else
					vbuf_free((video_buffer_t*)(msg->buffer));
			}
		}
		else if (msg->cmd == STORAGE_CMD_LOCK) {
			streamInfo_t *streamHandle = (streamInfo_t *) msg->handle;
			storageHandle_t *storageHandle = (storageHandle_t*) streamHandle->storageHandle;
			
			if(storageHandle->hdMux)
				g_save_Mux->set(storageHandle->hdMux, MUX_LOCK_FILE, 0);
		}
		else if (msg->cmd == STORAGE_CMD_FINISH) {
			streamInfo_t *streamHandle = (streamInfo_t *) msg->handle;
			storageHandle_t *storageHandle = (storageHandle_t*) streamHandle->storageHandle;
			//is_finish =1;
			if (storageHandle){
				if (storageHandle->hdMux) {
					g_save_Mux->close(storageHandle->hdMux);
					storageHandle->hdMux = 0;
				}
				if(storageHandle->file)
					fclose(storageHandle->file);
            	
				free(storageHandle);
				streamHandle->storageHandle = NULL;
				sync(); 
			}
		}
		else if (msg->cmd == STORAGE_CMD_CLOSE) {
			mq_close(storageMsgQ);
			break;
		}
	}
	printf("\nStorage thread exit ...\n\n");
}
示例#5
0
session::~session()
{
	reset();
	vbuf_free(sid_);
}
示例#6
0
bool session::flush()
{
	if (!dirty_)
		return true;
	dirty_ = false;

	string buf(256);

	// 调用纯虚接口,获得原来的 sid 数据
	if (get_data(sid_->buf, buf) == true)
	{
		if (!sid_saved_)
			sid_saved_ = true;
		deserialize(buf, attrs_);  // 反序列化
	}

	std::map<string, VBUF*>::iterator it_cache = attrs_cache_.begin();
	for (; it_cache != attrs_cache_.end(); ++it_cache)
	{
		// 如果该属性已存在,则需要先释放原来的属性值后再添加新值

		std::map<string, VBUF*>::iterator it_attr =
			attrs_.find(it_cache->first);
		if (it_attr == attrs_.end())
		{
			if (it_cache->second->todo == TODO_SET)
				attrs_[it_cache->first] = it_cache->second;
			else
				vbuf_free(it_cache->second);
		}
		else if (it_cache->second->todo == TODO_SET)
		{
			// 清除旧的数据
			vbuf_free(it_attr->second);
			// 设置新的数据
			attrs_[it_cache->first] = it_cache->second;
		}
		else if (it_cache->second->todo == TODO_DEL)
		{
			vbuf_free(it_attr->second);
			attrs_.erase(it_attr);
			vbuf_free(it_cache->second);
		}
		else
		{
			logger_warn("unknown todo(%d)", (int) it_cache->second->todo);
			vbuf_free(it_cache->second);
		}
	}

	// 清除缓存的数据:因为内部的数据已经被添加至 attrs_ 中,
	// 所以只需要将 attrs_cache_ 空间清除即可
	attrs_cache_.clear();

	serialize(attrs_, buf);  // 序列化数据
	attrs_clear(attrs_);  // 清除属性集合数据

	// 调用纯虚接口,向 memcached 或类似缓存中添加数据
	if (set_data(sid_->buf, buf.c_str(), buf.length(), ttl_) == false)
	{
		logger_error("set cache error, sid(%s)", sid_->buf);
		return false;
	}

	if (!sid_saved_)
		sid_saved_ = true;
	return true;
}