コード例 #1
0
ファイル: schedule.c プロジェクト: MarkieMark/netsurf-git-svn
void schedule(int t, void (*callback)(void *p), void *p)
{
	struct sched_entry *entry;
	struct sched_entry *queue;
	os_t time;

	schedule_remove(callback, p);

	time = os_read_monotonic_time() + t;

	entry = malloc(sizeof *entry);
	if (!entry) {
		LOG(("malloc failed"));
		return;
	}

	entry->time = time;
	entry->callback = callback;
	entry->p = p;

	for (queue = &sched_queue;
			queue->next && queue->next->time <= time;
			queue = queue->next)
		;
	entry->next = queue->next;
	queue->next = entry;

	sched_active = true;
	sched_time = sched_queue.next->time;
}
コード例 #2
0
ファイル: thread.c プロジェクト: jrepan/rhombus
struct thread *thread_freeze(struct thread *thread) {

	if (!thread->frozen) {
		schedule_remove(thread);
	}

	thread->frozen++;

	return thread;
}
コード例 #3
0
ファイル: debugwin.c プロジェクト: MarkieMark/netsurf-git-svn
void ro_gui_debugwin_close(wimp_w w)
{
	os_error *error;
	error = xwimp_close_window(dialog_debug);
	if (error) {
		LOG(("xwimp_close_window: 0x%x: %s",
				error->errnum, error->errmess));
		warn_user("WimpError", error->errmess);
	}
	schedule_remove(ro_gui_debugwin_update, 0);
	ro_gui_wimp_event_finalise(dialog_debug);
}
コード例 #4
0
ファイル: gui.c プロジェクト: galexcode/NetSurf68k
void gui_window_stop_throbber(struct gui_window *w)
{
    if (w == NULL)
        return;
    if (w->root->toolbar->throbber.running == false)
        return;

    schedule_remove(throbber_advance, w);

    toolbar_set_throbber_state(w->root->toolbar, false);

    rendering = false;
}
コード例 #5
0
ファイル: debugwin.c プロジェクト: MarkieMark/netsurf-git-svn
void ro_gui_debugwin_open(void)
{
#ifdef ENABLE_DEBUGWIN
	ro_gui_wimp_event_register_close_window(dialog_debug,
			ro_gui_debugwin_close);
	ro_gui_wimp_event_register_redraw_window(dialog_debug,
			ro_gui_debugwin_redraw);
	ro_gui_debugwin_resize();
	ro_gui_dialog_open(dialog_debug);
	schedule_remove(ro_gui_debugwin_update, 0);
	schedule(DEBUGWIN_UPDATE, ro_gui_debugwin_update, 0);
#endif
}
コード例 #6
0
ファイル: schedule.c プロジェクト: quakenet/newserv
void deleteallschedules(ScheduleCallback callback) {
  schedule *sp;
  int i;
  
trydel:
  /* OK, this gets to be REALLY cheesy and stupidly slow as well */
  
  for(i=0;i<heapsize;i++) {
    if (events[i]->callback==callback) {
      sp=events[i];
      schedule_remove(sp->index);
      freeschedule(sp);
      goto trydel;
    }
  }
}
コード例 #7
0
ファイル: thread.c プロジェクト: jrepan/rhombus
void thread_free(struct thread *thread) {
	uintptr_t i;

	/* free FPU/SSE data */
	if (thread->fxdata) {
		heap_free(thread->fxdata, 512);
		thread->fxdata = NULL;
	}

	/* remove thread from scheduler */
	schedule_remove(thread);

	/* free message packet if it exists */
	if (thread->msg) {
		
		/* free packet contents */
		for (i = 0; i < thread->msg->count; i++) {
			frame_free(thread->msg->frame[i]);
		}

		/* free the message packet structure */
		heap_free(thread->msg->frame, thread->msg->count * sizeof(uint32_t));
		heap_free(thread->msg, sizeof(struct msg));

	}

	/* free thread local storage if it exists */
	if (thread->stack) {
		i = (thread->stack - SSPACE) / SEGSZ;

		thread->proc->thread[i] = NULL;

		space_exmap(thread->proc->space);
	
		for (i = thread->stack; i < thread->stack + SEGSZ; i += PAGESZ) {
			if ((page_exget(i) & PF_PRES) != 0) {
				frame_free(page_ufmt(page_exget(i)));
				page_exset(i, 0);
			}
		}
	}

	/* free thread structure */
	heap_free(thread, sizeof(struct thread));
}
コード例 #8
0
ファイル: html_css.c プロジェクト: pombredanne/NetSurf
/* exported interface documented in render/html_internal.h */
nserror html_css_free_stylesheets(html_content *html)
{
    unsigned int i;

    schedule_remove(html_css_process_modified_styles, html);

    for (i = 0; i != html->stylesheet_count; i++) {
        if (html->stylesheets[i].sheet != NULL) {
            hlcache_handle_release(html->stylesheets[i].sheet);
        }
        if (html->stylesheets[i].node != NULL) {
            dom_node_unref(html->stylesheets[i].node);
        }
    }
    free(html->stylesheets);

    return NSERROR_OK;
}
コード例 #9
0
ファイル: download.c プロジェクト: seanregan/browser
void gui_download_window_error(struct gui_download_window *dw,
		const char *error_msg)
{
	os_error *error;

	if (dw->ctx != NULL)
		download_context_destroy(dw->ctx);
	dw->ctx = NULL;
	dw->error = true;

	schedule_remove(ro_gui_download_update_status_wrapper, dw);

	/* place error message in status icon in red */
	strncpy(dw->status, error_msg, sizeof dw->status);
	error = xwimp_set_icon_state(dw->window,
			ICON_DOWNLOAD_STATUS,
			wimp_COLOUR_RED << wimp_ICON_FG_COLOUR_SHIFT,
			wimp_ICON_FG_COLOUR);
	if (error) {
		LOG(("xwimp_set_icon_state: 0x%x: %s",
				error->errnum, error->errmess));
		warn_user("WimpError", error->errmess);
	}

	/* grey out pathname icon */
	error = xwimp_set_icon_state(dw->window, ICON_DOWNLOAD_PATH,
			wimp_ICON_SHADED, 0);
	if (error) {
		LOG(("xwimp_set_icon_state: 0x%x: %s",
				error->errnum, error->errmess));
		warn_user("WimpError", error->errmess);
	}

	/* grey out file icon */
	error = xwimp_set_icon_state(dw->window, ICON_DOWNLOAD_ICON,
			wimp_ICON_SHADED, wimp_ICON_SHADED);
	if (error) {
		LOG(("xwimp_set_icon_state: 0x%x: %s",
				error->errnum, error->errmess));
		warn_user("WimpError", error->errmess);
	}

	ro_gui_download_window_hide_caret(dw);
}
コード例 #10
0
ファイル: schedule.c プロジェクト: EyMenZ/NetSurf-OS3
/* exported function documented in riscos/gui.h */
nserror riscos_schedule(int t, void (*callback)(void *p), void *p)
{
	struct sched_entry *entry;
	struct sched_entry *queue;
	os_t time;
	nserror ret;

	ret = schedule_remove(callback, p);
	if ((t < 0) || (ret != NSERROR_OK)) {
		return ret;
	}

	t = t / 10; /* convert to centiseconds */

	time = os_read_monotonic_time() + t;

	entry = malloc(sizeof *entry);
	if (!entry) {
		LOG("malloc failed");
		return NSERROR_NOMEM;
	}

	entry->time = time;
	entry->callback = callback;
	entry->p = p;

	for (queue = &sched_queue;
			queue->next && queue->next->time <= time;
			queue = queue->next)
		;
	entry->next = queue->next;
	queue->next = entry;

	sched_active = true;
	sched_time = sched_queue.next->time;

	return NSERROR_OK;
}
コード例 #11
0
ファイル: rtspservice.c プロジェクト: michalliu/rtspserver
int RTSP_teardown(RTSP_buffer * pRtsp)
{
	char *pStr;
	char pTrash[128];
	long int s32SessionId;
	RTSP_session *pRtspSesn;
	RTP_session *pRtpSesn;

	//获取CSeq
	if ((pStr = strstr(pRtsp->in_buffer, HDR_CSEQ)) == NULL)
	{
		send_reply(400, 0, pRtsp);   // Bad Request
		printf("get CSeq error");
		return ERR_NOERROR;
	}
	else
	{
		if (sscanf(pStr, "%254s %d", pTrash, &(pRtsp->rtsp_cseq)) != 2)
		{
			send_reply(400, 0, pRtsp);    // Bad Request
			printf("get CSeq 2 error");
			return ERR_NOERROR;
		}
	}

	//获取session
	if ((pStr = strstr(pRtsp->in_buffer, HDR_SESSION)) != NULL)
	{
		if (sscanf(pStr, "%254s %ld", pTrash, &s32SessionId) != 2)
		{
			send_reply(454, 0, pRtsp);	// Session Not Found
			return ERR_NOERROR;
		}
	}
	else
	{
		s32SessionId = -1;
	}

	pRtspSesn = pRtsp->session_list;
	if (pRtspSesn == NULL)
	{
		send_reply(415, 0, pRtsp);  // Internal server error
		return ERR_GENERIC;
	}

	if (pRtspSesn->session_id != s32SessionId)
	{
		send_reply(454, 0, pRtsp);	// Session not found
		return ERR_NOERROR;
	}

	//向客户端发送响应消息
	send_teardown_reply(pRtsp, s32SessionId, pRtsp->rtsp_cseq);

	//释放所有的URI RTP会话
	RTP_session *pRtpSesnTemp;
	pRtpSesn = pRtspSesn->rtp_session;
	while (pRtpSesn != NULL)
	{
		pRtpSesnTemp = pRtpSesn;

		pRtspSesn->rtp_session = pRtpSesn->next;

		pRtpSesn = pRtpSesn->next;

		//删除RTP视频发送
		RtpDelete((unsigned int)pRtpSesnTemp->hndRtp);
		//删除schedule中对应id
		schedule_remove(pRtpSesnTemp->sched_id);
		//全局变量播放总数减一,如果为0则不播放
		g_s32DoPlay--;

	}

	//释放链表空间
	if (pRtspSesn->rtp_session == NULL)
	{
		free(pRtsp->session_list);
		pRtsp->session_list = NULL;
	}

	return ERR_NOERROR;
}
コード例 #12
0
ファイル: download.c プロジェクト: seanregan/browser
void ro_gui_download_update_status(struct gui_download_window *dw)
{
	char *received;
	char *total_size;
	char *speed;
	char time[20] = "?";
	struct timeval t;
	float dt;
	unsigned int left;
	float rate;
	os_error *error;
	int width;
	char *local_status;
	utf8_convert_ret err;

	gettimeofday(&t, 0);
	dt = (t.tv_sec + 0.000001 * t.tv_usec) - (dw->last_time.tv_sec +
			0.000001 * dw->last_time.tv_usec);
	if (dt == 0)
		dt = 0.001;

	total_size = human_friendly_bytesize(max(dw->received, dw->total_size));

	if (dw->ctx) {
		rate = (dw->received - dw->last_received) / dt;
		received = human_friendly_bytesize(dw->received);
		/* A simple 'modified moving average' download rate calculation
		 * to smooth out rate fluctuations: chosen for simplicity.
		 */
		dw->average_points++;
		dw->average_rate =
				((dw->average_points - 1) *
				dw->average_rate + rate) /
				dw->average_points;
		speed = human_friendly_bytesize(dw->average_rate);
		if (dw->total_size) {
			float f;

			if (dw->average_rate > 0) {
				left = (dw->total_size - dw->received) /
						dw->average_rate;
				sprintf(time, "%u:%.2u", left / 60, left % 60);
			}

			/* convert to local encoding */
			err = utf8_to_local_encoding(
				messages_get("Download"), 0, &local_status);
			if (err != UTF8_CONVERT_OK) {
				/* badenc should never happen */
				assert(err != UTF8_CONVERT_BADENC);
				/* hide nomem error */
				snprintf(dw->status, sizeof dw->status,
					messages_get("Download"),
					received, total_size, speed, time);
			}
			else {
				snprintf(dw->status, sizeof dw->status,
					local_status,
					received, total_size, speed, time);
				free(local_status);
			}

			f = (float) dw->received / (float) dw->total_size;
			width = download_progress_width * f;
		} else {
			left = t.tv_sec - dw->start_time.tv_sec;
			sprintf(time, "%u:%.2u", left / 60, left % 60);

			err = utf8_to_local_encoding(
				messages_get("DownloadU"), 0, &local_status);
			if (err != UTF8_CONVERT_OK) {
				/* badenc should never happen */
				assert(err != UTF8_CONVERT_BADENC);
				/* hide nomem error */
				snprintf(dw->status, sizeof dw->status,
					messages_get("DownloadU"),
					received, speed, time);
			}
			else {
				snprintf(dw->status, sizeof dw->status,
					local_status,
					received, speed, time);
				free(local_status);
			}

			/* length unknown, stay at 0 til finished */
			width = 0;
		}
	} else {
		left = dw->last_time.tv_sec - dw->start_time.tv_sec;
		if (left == 0)
			left = 1;
		rate = (float) dw->received / (float) left;
		sprintf(time, "%u:%.2u", left / 60, left % 60);
		speed = human_friendly_bytesize(rate);

		err = utf8_to_local_encoding(messages_get("Downloaded"), 0,
				&local_status);
		if (err != UTF8_CONVERT_OK) {
			/* badenc should never happen */
			assert(err != UTF8_CONVERT_BADENC);
			/* hide nomem error */
			snprintf(dw->status, sizeof dw->status,
				messages_get("Downloaded"),
				total_size, speed, time);
		}
		else {
			snprintf(dw->status, sizeof dw->status, local_status,
					total_size, speed, time);
			free(local_status);
		}

		/* all done */
		width = download_progress_width;
	}

	dw->last_time = t;
	dw->last_received = dw->received;

	error = xwimp_resize_icon(dw->window, ICON_DOWNLOAD_PROGRESS,
			download_progress_x0,
			download_progress_y0,
			download_progress_x0 + width,
			download_progress_y1);
	if (error) {
		LOG(("xwimp_resize_icon: 0x%x: %s",
				error->errnum, error->errmess));
		warn_user("WimpError", error->errmess);
	}

	error = xwimp_set_icon_state(dw->window, ICON_DOWNLOAD_STATUS, 0, 0);
	if (error) {
		LOG(("xwimp_set_icon_state: 0x%x: %s",
				error->errnum, error->errmess));
		warn_user("WimpError", error->errmess);
	}

	if (dw->ctx)
		schedule(100, ro_gui_download_update_status_wrapper, dw);
	else
		schedule_remove(ro_gui_download_update_status_wrapper, dw);
}
コード例 #13
0
ファイル: download.c プロジェクト: seanregan/browser
bool ro_gui_download_window_destroy(struct gui_download_window *dw, bool quit)
{
	bool safe = dw->saved && !dw->ctx;
	os_error *error;

	if (!safe && !dw->close_confirmed)
	{
		query_reason rsn = quit ? QueryRsn_Quit : QueryRsn_Abort;

		if (dw->query != QUERY_INVALID) {

			/* can we just reuse the existing query? */
			if (rsn == dw->query_rsn) {
				ro_gui_query_window_bring_to_front(dw->query);
				return false;
			}

			query_close(dw->query);
			dw->query = QUERY_INVALID;
		}

		if (quit) {
			/* bring all download windows to the front of the desktop as
			   a convenience if there are lots of windows open */

			struct gui_download_window *d = download_window_list;
			while (d) {
				ro_gui_dialog_open_top(d->window, NULL, 0, 0);
				d = d->next;
			}
		}

		dw->query_rsn = rsn;
		dw->query = query_user(quit ? "QuitDownload" : "AbortDownload",
				NULL, &close_funcs, dw, NULL, NULL);

		return false;
	}

	schedule_remove(ro_gui_download_update_status_wrapper, dw);
	schedule_remove(ro_gui_download_window_destroy_wrapper, dw);

	/* remove from list */
	if (dw->prev)
		dw->prev->next = dw->next;
	else
		download_window_list = dw->next;
	if (dw->next)
		dw->next->prev = dw->prev;

	/* delete window */
	error = xwimp_delete_window(dw->window);
	if (error) {
		LOG(("xwimp_delete_window: 0x%x: %s",
				error->errnum, error->errmess));
		warn_user("WimpError", error->errmess);
	}
	ro_gui_wimp_event_finalise(dw->window);

	/* close download file */
	if (dw->file) {
		error = xosfind_closew(dw->file);
		if (error) {
			LOG(("xosfind_closew: 0x%x: %s",
					error->errnum, error->errmess));
			warn_user("SaveError", error->errmess);
		}
	}

	/* delete temporary file */
	if (!dw->saved) {
		const char *temp_name = ro_gui_download_temp_name(dw);

		error = xosfile_delete(temp_name, 0, 0, 0, 0, 0);
		if (error) {
			LOG(("xosfile_delete: 0x%x: %s",
					error->errnum, error->errmess));
			warn_user("SaveError", error->errmess);
		}
	}

	if (dw->ctx) {
		download_context_abort(dw->ctx);
		download_context_destroy(dw->ctx);
	}

	free(dw);

	return true;
}
コード例 #14
0
/* exported interface documented in image_cache.h */
nserror image_cache_fini(void)
{
	unsigned int op_count;

	schedule_remove(image_cache__background_update, image_cache);

	LOG(("Size at finish %d (in %d)",
	     image_cache->total_bitmap_size,
	     image_cache->bitmap_count));

	while (image_cache->entries != NULL) {
		image_cache__free_entry(image_cache->entries);
	}

	op_count = image_cache->hit_count +
		image_cache->miss_count +
		image_cache->fail_count;

	LOG(("Age %ds", image_cache->current_age / 1000));
	LOG(("Peak size %d (in %d)",
	     image_cache->max_bitmap_size,
	     image_cache->max_bitmap_size_count ));
	LOG(("Peak image count %d (size %d)",
	     image_cache->max_bitmap_count,
	     image_cache->max_bitmap_count_size));

	if (op_count > 0) {
		uint64_t op_size;

		op_size = image_cache->hit_size +
			image_cache->miss_size +
			image_cache->fail_size;

		LOG(("Cache total/hit/miss/fail (counts) %d/%d/%d/%d (100%%/%d%%/%d%%/%d%%)",
		     op_count,
		     image_cache->hit_count,
		     image_cache->miss_count,
		     image_cache->fail_count,
		     (image_cache->hit_count * 100) / op_count,
		     (image_cache->miss_count * 100) / op_count,
		     (image_cache->fail_count * 100) / op_count));
		LOG(("Cache total/hit/miss/fail (size) %d/%d/%d/%d (100%%/%d%%/%d%%/%d%%)",
		     op_size,
		     image_cache->hit_size,
		     image_cache->miss_size,
		     image_cache->fail_size,
		     (image_cache->hit_size * 100) / op_size,
		     (image_cache->miss_size * 100) / op_size,
		     (image_cache->fail_size * 100) / op_size));
	}

	LOG(("Total images never rendered: %d (includes %d that were converted)",
	     image_cache->total_unrendered,
	     image_cache->specultive_miss_count));

	LOG(("Total number of excessive conversions: %d (from %d images converted more than once)",
	     image_cache->total_extra_conversions,
	     image_cache->total_extra_conversions_count));

	LOG(("Bitmap of size %d had most (%d) conversions",
	     image_cache->peak_conversions_size,
	     image_cache->peak_conversions));

	free(image_cache);

	return NSERROR_OK;
}
コード例 #15
0
/* See hlcache.h for documentation */
void hlcache_stop(void)
{
	/* Remove the hlcache_clean schedule */
	schedule_remove(hlcache_clean, NULL);
}
コード例 #16
0
ファイル: RTSP_teardown.c プロジェクト: iamnpc/fenice-1.11
int RTSP_teardown(RTSP_buffer * rtsp)
{
	long int session_id;
	char *p;
	RTSP_session *s;
	RTP_session *rtp_curr, *rtp_prev = NULL, *rtp_temp;
	int valid_url;
	char object[255], server[255], trash[255], *filename;
	unsigned short port;
	char url[255];
	unsigned int cseq;

	// CSeq
	if ((p = strstr(rtsp->in_buffer, HDR_CSEQ)) == NULL) {
		send_reply(400, 0, rtsp);	/* Bad Request */
		return ERR_PARSE;
	} else {
		if (sscanf(p, "%254s %d", trash, &(rtsp->rtsp_cseq)) != 2) {
			send_reply(400, 0, rtsp);	/* Bad Request */
			return ERR_PARSE;
		}
	}
	cseq = rtsp->rtsp_cseq;
	/* Extract the URL */
	if (!sscanf(rtsp->in_buffer, " %*s %254s ", url)) {
		send_reply(400, 0, rtsp);	/* bad request */
		return ERR_PARSE;
	}
	/* Validate the URL */
	switch (parse_url(url, server, sizeof(server), &port, object, sizeof(object))) {
		case 1: // bad request
			send_reply(400, 0, rtsp);
			return ERR_PARSE;
			break;
		case -1: // internal server error
			send_reply(500, 0, rtsp);
			return ERR_PARSE;
			break;
		default:
			break;
	}
	if (strcmp(server, prefs_get_hostname()) != 0) {	/* Currently this feature is disabled. */
		/* wrong server name */
		//      send_reply(404, 0 , rtsp); /* Not Found */
		//      return ERR_PARSE;
	}
	if (strstr(object, "../")) {
		/* disallow relative paths outside of current directory. */
		send_reply(403, 0, rtsp);	/* Forbidden */
		return ERR_PARSE;
	}
	if (strstr(object, "./")) {
		/* Disallow ./ */
		send_reply(403, 0, rtsp);	/* Forbidden */
		return ERR_PARSE;
	}
	p = strrchr(object, '.');
	valid_url = 0;
	if (p == NULL) {
		send_reply(415, 0, rtsp);	/* Unsupported media type */
		return ERR_PARSE;
	} else {
		valid_url = is_supported_url(p);
	}
	if (!valid_url) {
		send_reply(415, 0, rtsp);	/* Unsupported media type */
		return ERR_PARSE;
	}
	// Session
	if ((p = strstr(rtsp->in_buffer, HDR_SESSION)) != NULL) {
		if (sscanf(p, "%254s %ld", trash, &session_id) != 2) {
			send_reply(454, 0, rtsp);	/* Session Not Found */
			return ERR_PARSE;
			// return ERR_NOERROR;
		}
	} else {
		session_id = -1;
	}
	s = rtsp->session_list;
	if (s == NULL) {
		send_reply(415, 0, rtsp);	// Internal server error
		return ERR_GENERIC;
	}
	if (s->session_id != session_id) {
		send_reply(454, 0, rtsp);	/* Session Not Found */
		return ERR_PARSE;
	}

	fnc_log(FNC_LOG_INFO,"TEARDOWN %s RTSP/1.0 ",url);
	send_teardown_reply(rtsp, session_id, cseq);
	// See User-Agent 
	if ((p=strstr(rtsp->in_buffer, HDR_USER_AGENT))!=NULL) {
		char cut[strlen(p)];
		strcpy(cut,p);
		p=strstr(cut, "\n");
		cut[strlen(cut)-strlen(p)-1]='\0';
		fnc_log(FNC_LOG_CLIENT,"%s\n",cut);
	}
	else
		fnc_log(FNC_LOG_CLIENT,"- \n");

	
	if (strchr(object, '!'))	/*Compatibility with RealOne and RealPlayer */
		filename = strchr(object, '!') + 1;
	else
		filename = object;



	// Release all URI RTP session
	rtp_curr = s->rtp_session;
	while (rtp_curr != NULL) {
		if (strcmp(rtp_curr->current_media->filename, filename) == 0
		    || strcmp(rtp_curr->current_media->aggregate, filename) == 0) {
			rtp_temp = rtp_curr;
			if (rtp_prev != NULL)
				rtp_prev->next = rtp_curr->next;
			else
				s->rtp_session = rtp_curr->next;
			rtp_curr = rtp_curr->next;
			// Release the scheduler entry
			schedule_remove(rtp_temp->sched_id);
			// Close connections
		} else {
			rtp_prev = rtp_curr;
			rtp_curr = rtp_curr->next;
		}
	}

	if (s->rtp_session == NULL) {
		// Close connection
		//close(s->fd);
		// Release the RTSP session
		free(rtsp->session_list);
		rtsp->session_list = NULL;
	}
	
	return ERR_NOERROR;
}
コード例 #17
0
ファイル: rtspservice.c プロジェクト: michalliu/rtspserver
void ScheduleConnections(RTSP_buffer **rtsp_list, int *conn_count)
{
    int res;
    RTSP_buffer *pRtsp=*rtsp_list,*pRtspN=NULL;
    RTP_session *r=NULL, *t=NULL;

#ifdef RTSP_DEBUG
//    fprintf(stderr, "%s\n", __FUNCTION__);
#endif

    while (pRtsp!=NULL)
    {
        if ((res = RtspServer(pRtsp))!=ERR_NOERROR)
        {
            if (res==ERR_CONNECTION_CLOSE || res==ERR_GENERIC)
            {
                /*连接已经关闭*/
                if (res==ERR_CONNECTION_CLOSE)
                    fprintf(stderr,"fd:%d,RTSP connection closed by client.\n",pRtsp->fd);
                else
                	fprintf(stderr,"fd:%d,RTSP connection closed by server.\n",pRtsp->fd);

                /*客户端在发送TEARDOWN 之前就截断了连接,但是会话却没有被释放*/
                if (pRtsp->session_list!=NULL)
                {
                    r=pRtsp->session_list->rtp_session;
                    /*释放所有会话*/
                    while (r!=NULL)
                    {
                        t = r->next;
                        RtpDelete((unsigned int)(r->hndRtp));
                        schedule_remove(r->sched_id);
                        r=t;
                    }

                    /*释放链表头指针*/
                    free(pRtsp->session_list);
                    pRtsp->session_list=NULL;

                    g_s32DoPlay--;

                    fprintf(stderr,"WARNING! RTSP connection truncated before ending operations.\n");
                }

                // wait for
                close(pRtsp->fd);
                --*conn_count;
                num_conn--;

                /*释放rtsp缓冲区*/
                if (pRtsp==*rtsp_list)
                {
                	//链表第一个元素就出错,则pRtspN为空
                    *rtsp_list=pRtsp->next;
                    free(pRtsp);
                    pRtsp=*rtsp_list;
                }
                else
                {
                	//不是链表中的第一个,则把当前出错任务删除,并把next任务存放在pRtspN(上一个没有出错的任务)
                	//指向的next,和当前需要处理的pRtsp中.
                	pRtspN->next=pRtsp->next;
                    free(pRtsp);
                    pRtsp=pRtspN->next;
                }

                /*适当情况下,释放调度器本身*/
                if (pRtsp==NULL && *conn_count<0)
                {
                	fprintf(stderr,"to stop cchedule_do thread\n");
                    stop_schedule=1;
                }
            }
            else
            {
            	pRtsp = pRtsp->next;
            }
        }
        else
        {
			//printf("6\r\n");
        	//没有出错
        	//上一个处理没有出错的list存放在pRtspN中,需要处理的任务放在pRtst中
        	pRtspN = pRtsp;
            pRtsp = pRtsp->next;
        }
    }
}