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; }
struct thread *thread_freeze(struct thread *thread) { if (!thread->frozen) { schedule_remove(thread); } thread->frozen++; return thread; }
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); }
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; }
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 }
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; } } }
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)); }
/* 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; }
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); }
/* 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; }
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; }
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); }
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; }
/* 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; }
/* See hlcache.h for documentation */ void hlcache_stop(void) { /* Remove the hlcache_clean schedule */ schedule_remove(hlcache_clean, NULL); }
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; }
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; } } }