本文整理汇总了C++中complete_and_exit函数的典型用法代码示例。如果您正苦于以下问题:C++ complete_and_exit函数的具体用法?C++ complete_and_exit怎么用?C++ complete_and_exit使用的例子?那么恭喜您, 这里精选的函数代码示例或许可以为您提供帮助。
在下文中一共展示了complete_and_exit函数的20个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于我们的系统推荐出更棒的C++代码示例。
示例1: usb_hub_thread
static int usb_hub_thread(void *startup)
{
lock_kernel();
/*
* This thread doesn't need any user-level access,
* so get rid of all our resources
*/
daemonize();
reparent_to_init();
/* Block all signals */
spin_lock_irq(¤t->sigmask_lock);
sigfillset(¤t->blocked);
recalc_sigpending(current);
spin_unlock_irq(¤t->sigmask_lock);
/* Setup a nice name */
strcpy(current->comm, "khubd");
khubd_terminated = 0;
complete((struct completion *)startup);
/* Set khubd_terminated=1 to get me die */
do {
usb_hub_events();
wait_event_interruptible(khubd_wait, !list_empty(&hub_event_list) || khubd_terminated);
} while (!khubd_terminated || !list_empty(&hub_event_list));
dbg("usb_hub_thread exiting");
unlock_kernel();
complete_and_exit(&khubd_exited, 0);
}
开发者ID:NieHao,项目名称:Tomato-RAF,代码行数:35,代码来源:hub.c
示例2: xio_server_main
/*---------------------------------------------------------------------------*/
static int xio_server_main(void *data)
{
struct xio_server *server;
struct xio_context_params ctx_params;
init_xio_rdma_common_test();
memset(&ctx_params, 0, sizeof(ctx_params));
ctx_params.flags = XIO_LOOP_GIVEN_THREAD;
ctx_params.worker = current;
test_params.ctx = xio_context_create(&ctx_params, 0, 0);
xio_assert(test_params.ctx);
session_ops.on_session_event = on_session_event;
server = xio_bind(test_params.ctx, &session_ops,
url, NULL, 0, NULL);
xio_assert(server);
pr_info("listen to %s\n", url);
xio_context_run_loop(test_params.ctx);
/* normal exit phase */
pr_info("exit signaled\n");
/* free the server */
xio_unbind(server);
xio_context_destroy(test_params.ctx);
fini_xio_rdma_common_test();
complete_and_exit(&cleanup_complete, 0);
return 0;
}
开发者ID:SUSE,项目名称:accelio,代码行数:35,代码来源:xio_server.c
示例3: iGreetingFrameThread
/****************************************************************************
* Function (run in a thread) which changes the screen contents during a fixed
* time period following module initialisation, then disappears.
* Ideally we'd provide a way to kill this thread if the module gets unloaded
* before it finishes its work...
****************************************************************************/
static int iGreetingFrameThread(void *arg)
{
up(&start_thread_sem);
set_current_state(TASK_INTERRUPTIBLE);
schedule_timeout(banner_update_time_secs * HZ); /* sleep */
vDrawGreetingFrame(2);
complete_and_exit(&greeting_frame_complete, 0);
}
开发者ID:philsmd,项目名称:sharpfin,代码行数:14,代码来源:lcd_generic.c
示例4: MlmeThread
/*
========================================================================
Routine Description:
MLME kernel thread.
Arguments:
*Context the pAd, driver control block pointer
Return Value:
0 close the thread
Note:
========================================================================
*/
INT MlmeThread(
IN ULONG Context)
{
RTMP_ADAPTER *pAd;
RTMP_OS_TASK *pTask;
int status;
status = 0;
pTask = (RTMP_OS_TASK *)Context;
pAd = (PRTMP_ADAPTER)pTask->priv;
RtmpOSTaskCustomize(pTask);
while(!pTask->task_killed)
{
#ifdef KTHREAD_SUPPORT
RTMP_WAIT_EVENT_INTERRUPTIBLE(pAd, pTask);
#else
RTMP_SEM_EVENT_WAIT(&(pTask->taskSema), status);
/* unlock the device pointers */
if (status != 0)
{
RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS);
break;
}
#endif
/* lock the device pointers , need to check if required*/
//down(&(pAd->usbdev_semaphore));
if (!pAd->PM_FlgSuspend)
MlmeHandler(pAd);
}
/* notify the exit routine that we're actually exiting now
*
* complete()/wait_for_completion() is similar to up()/down(),
* except that complete() is safe in the case where the structure
* is getting deleted in a parallel mode of execution (i.e. just
* after the down() -- that's necessary for the thread-shutdown
* case.
*
* complete_and_exit() goes even further than this -- it is safe in
* the case that the thread of the caller is going away (not just
* the structure) -- this is necessary for the module-remove case.
* This is important in preemption kernels, which transfer the flow
* of execution immediately upon a complete().
*/
DBGPRINT(RT_DEBUG_TRACE,( "<---%s\n",__FUNCTION__));
#ifndef KTHREAD_SUPPORT
pTask->taskPID = THREAD_PID_INIT_VALUE;
complete_and_exit (&pTask->taskComplete, 0);
#endif
return 0;
}
开发者ID:nuvotonmcu,项目名称:applications,代码行数:71,代码来源:usb_main_dev.c
示例5: __thread_exit
void
__thread_exit(void)
{
SENTRY;
SEXIT;
tsd_exit();
complete_and_exit(NULL, 0);
/* Unreachable */
}
开发者ID:csiden,项目名称:spl,代码行数:9,代码来源:spl-thread.c
示例6: async_task
/* thread to serialize all requests, both sync and async */
static int async_task(void *param)
{
HIF_DEVICE *device;
BUS_REQUEST *request;
A_STATUS status;
unsigned long flags;
device = (HIF_DEVICE *)param;
AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: async task\n"));
set_current_state(TASK_INTERRUPTIBLE);
while(!device->async_shutdown) {
/* wait for work */
if (down_interruptible(&device->sem_async) != 0) {
/* interrupted, exit */
AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: async task interrupted\n"));
break;
}
if (device->async_shutdown) {
AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: async task stopping\n"));
break;
}
/* we want to hold the host over multiple cmds if possible, but holding the host blocks card interrupts */
sdio_claim_host(device->func);
spin_lock_irqsave(&device->asynclock, flags);
/* pull the request to work on */
while (device->asyncreq != NULL) {
request = device->asyncreq;
if (request->inusenext != NULL) {
device->asyncreq = request->inusenext;
} else {
device->asyncreq = NULL;
}
spin_unlock_irqrestore(&device->asynclock, flags);
/* call HIFReadWrite in sync mode to do the work */
AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: async_task processing req: 0x%X\n", (unsigned int)request));
status = __HIFReadWrite(device, request->address, request->buffer,
request->length, request->request & ~HIF_SYNCHRONOUS, NULL);
if (request->request & HIF_ASYNCHRONOUS) {
AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: async_task completion routine req: 0x%X\n", (unsigned int)request));
device->htcCallbacks.rwCompletionHandler(request->context, status);
AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: async_task freeing req: 0x%X\n", (unsigned int)request));
hifFreeBusRequest(device, request);
} else {
AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: async_task upping req: 0x%X\n", (unsigned int)request));
request->status = status;
up(&request->sem_req);
}
spin_lock_irqsave(&device->asynclock, flags);
}
spin_unlock_irqrestore(&device->asynclock, flags);
sdio_release_host(device->func);
}
complete_and_exit(&device->async_completion, 0);
return 0;
}
开发者ID:plaguedbypenguins,项目名称:atheros_sdk2,代码行数:57,代码来源:hif.c
示例7: ral_task_notify_exit
INT ral_task_notify_exit(
IN KTHREAD *pTask)
{
RTBT_OS_TASK *pOSThread = (RTBT_OS_TASK *)pTask->pOSThread;
#ifndef KTHREAD_SUPPORT
complete_and_exit(&pOSThread->taskComplete, 0);
#endif
return 0;
}
开发者ID:Valantin,项目名称:rtbth,代码行数:11,代码来源:rtbth_hlpr_linux.c
示例8: dump_thread
static int dump_thread(void *data)
{
struct rtc_device *rtc;
struct rtc_time tm;
int err = 0;
char log_file_name[100];
char backup_log_file_name[100];
pr_at_info("%s: Enter into dump_thread\n", __func__);
/* Dump the last kernel log */
/* MX have two rtc devices */
rtc = rtc_class_open("rtc0");
if (rtc == NULL) {
rtc = rtc_class_open("rtc1");
if (rtc == NULL) {
pr_err(ATP "%s: can not open rtc devices\n", __func__);
err = -ENODEV;
}
}
if (!err) {
err = rtc_read_time(rtc, &tm);
if (err)
pr_err(ATP "%s: unable to read the hardware clock\n", __func__);
}
sprintf(log_file_name, "%s-%d%02d%02d_%02d%02d%02d", CONFIG_LAST_KMSG_LOG_FILE,
tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,
tm.tm_hour + 8, tm.tm_min, tm.tm_sec);
pr_at_info("%s: Get log file name: %s\n", __func__, log_file_name);
err = dump_last_kmsg(log_file_name);
if (err) {
pr_err(ATP "%s: Failed dump kernel log to %s\n", __func__, log_file_name);
sprintf(backup_log_file_name, "%s-%d%02d%02d_%02d%02d%02d", CONFIG_BACKUP_LAST_KMSG_LOG_FILE,
tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,
tm.tm_hour + 8, tm.tm_min, tm.tm_sec);
pr_at_info("%s: Get backup log file name: %s\n", __func__, backup_log_file_name);
err = dump_last_kmsg(backup_log_file_name);
if (err) {
pr_err(ATP "%s: Failed dump kernel log to %s\n", __func__, backup_log_file_name);
goto out;
} else {
pr_at_info("%s: kernel log file dumped to %s\n", __func__, backup_log_file_name);
}
} else {
pr_at_info("%s: kernel log file dumped to %s\n", __func__, log_file_name);
}
out:
complete_and_exit(&dump, 0);
return err;
}
开发者ID:StormAll,项目名称:meizu-m9-kernel,代码行数:53,代码来源:autotest.c
示例9: spl_debug_dumplog_thread
static int
spl_debug_dumplog_thread(void *arg)
{
dumplog_priv_t *dp = (dumplog_priv_t *)arg;
spl_debug_dumplog_internal(dp);
atomic_set(&dp->dp_done, 1);
wake_up(&dp->dp_waitq);
complete_and_exit(NULL, 0);
return 0; /* Unreachable */
}
开发者ID:Kream,项目名称:spl,代码行数:12,代码来源:spl-debug.c
示例10: guest_mig_mode_handler
/** This handler is invoked when the sig_unused hook finds a non-NULL entry
* in the clondike record in the task_struct */
void guest_mig_mode_handler(void)
{
struct tcmi_task *tmp, *task;
int res;
long exit_code;
minfo(INFO1, "Migration mode handler for task '%s' executing",
current->comm);
if (!(task = tcmi_taskhelper_sanity_check())) {
minfo(ERR3, "Stub - invalid entry to migration mode - kernel task %p, PID=%d",
current, current->pid);
goto exit0;
}
/* keep moving the task between migration managers */
while ((res = tcmi_task_process_methods(task)) ==
TCMI_TASK_MOVE_ME);
/* check the result of the last method processed */
switch (res) {
case TCMI_TASK_KEEP_PUMPING:
minfo(INFO1, "KEEP PUMPING - but no methods left %d", res);
break;
case TCMI_TASK_LET_ME_GO:
minfo(INFO1, "LET ME GO - request %d", res);
break;
/* no need for special handling a fall through causes
* do_exit which sends a message to the shadow */
case TCMI_TASK_EXECVE_FAILED_KILL_ME:
minfo(INFO1, "EXECVE_FAILED KILL ME - request %d", res);
break;
case TCMI_TASK_KILL_ME:
minfo(INFO1, "KILL ME - request %d", res);
tmp = tcmi_taskhelper_detach();
/* get the exit code prior terminating. */
exit_code = tcmi_task_exit_code(tmp);
tcmi_task_put(tmp);
complete_and_exit(NULL, exit_code);
break;
case TCMI_TASK_REMOVE_AND_LET_ME_GO:
minfo(INFO1, "REMOVE AND LET ME GO - request %d", res);
tcmi_task_put(tcmi_taskhelper_detach());
break;
default:
minfo(ERR1, "Unexpected result %d.", res);
break;
}
/* error handling */
exit0:
return;
}
开发者ID:FIT-CVUT,项目名称:clondike,代码行数:54,代码来源:tcmi_ppm_p_guest_test.c
示例11: RTUSBCmdThread
INT RTUSBCmdThread(
IN void * Context)
{
PRTMP_ADAPTER pAd = (PRTMP_ADAPTER)Context;
//2007/12/11:KH modified to fix compiled failed
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
daemonize();
#else
daemonize("rt73");
#endif
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
allow_signal(SIGTERM);
#endif
current->flags |= PF_NOFREEZE;
/* signal that we've started the thread */
complete(&(pAd->CmdThreadNotify));
while (1)
{
int status;
status = down_interruptible(&(pAd->RTUSBCmd_semaphore));
if (status != 0)
continue;
if (RTUSBCmd_kill)
break;
pAd->CmdHandlerIsRunning=TRUE;
CMDHandler(pAd);
pAd->CmdHandlerIsRunning=FALSE;
}
/* notify the exit routine that we're actually exiting now
*
* complete()/wait_for_completion() is similar to up()/down(),
* except that complete() is safe in the case where the structure
* is getting deleted in a parallel mode of execution (i.e. just
* after the down() -- that's necessary for the thread-shutdown
* case.
*
* complete_and_exit() goes even further than this -- it is safe in
* the case that the thread of the caller is going away (not just
* the structure) -- this is necessary for the module-remove case.
* This is important in preemption kernels, which transfer the flow
* of execution immediately upon a complete().
*/
complete_and_exit (&pAd->CmdThreadNotify, 0);
DBGPRINT(RT_DEBUG_TRACE, "<---RTUSBCmdThread\n");
}
开发者ID:fgoncalves,项目名称:Ralink-Driver-Hack,代码行数:50,代码来源:rtmp_main.c
示例12: bcm63xx_timer
/*
* bcm63xx_timer: 100ms timer for updating rx rate control credits
*/
static void bcm63xx_timer(unsigned long arg)
{
BcmEnet_devctrl *priv;
BcmEnet_RxDma *rxdma;
unsigned int elapsed_msecs;
int i;
struct sched_param param;
daemonize("bcmsw_timer");
param.sched_priority = BCM_RTPRIO_DATA;
sched_setscheduler(current, SCHED_RR, ¶m);
set_user_nice(current, 0);
while (atomic_read(&timer_lock) > 0)
{
for (i = 0; i < iface_cnt; i++) {
ENET_RX_LOCK();
priv = (BcmEnet_devctrl *)netdev_priv(vnet_dev[i]);
if (rxchannel_rate_limit_enable[i]) {
elapsed_msecs = jiffies_to_msecs(jiffies -
last_pkt_jiffies[i]);
if (elapsed_msecs >= 99) {
rxdma = priv->rxdma[0];
BCM_ENET_DEBUG("pkts_from_last_jiffies = %d \n",
rx_pkts_from_last_jiffies[i]);
rx_pkts_from_last_jiffies[i] = 0;
last_pkt_jiffies[i] = jiffies;
if (rxchannel_isr_enable[i] == 0) {
BCM_ENET_DEBUG("Enabling DMA Channel & Interrupt \n");
/* Disable this. Should be implemented differently in
* impl6
switch_rx_ring(priv, 0, 0);
*/
bcmPktDma_BcmHalInterruptEnable(i, rxdma->rxIrq);
rxchannel_isr_enable[i] = 1;
}
}
}
ENET_RX_UNLOCK();
}
/* Sleep for HZ/10 jiffies (100ms) */
set_current_state(TASK_INTERRUPTIBLE);
schedule_timeout(HZ/10);
}
complete_and_exit(&timer_done, 0);
printk("bcm63xx_timer: thread exits!\n");
}
开发者ID:jameshilliard,项目名称:NCS_CS_1.1L.10.20_consumer,代码行数:52,代码来源:bcmenet_dma.c
示例13: rsi_coex_scheduler_thread
static void rsi_coex_scheduler_thread(struct rsi_common *common)
{
struct rsi_coex_ctrl_block *coex_cb =
(struct rsi_coex_ctrl_block *)common->coex_cb;
u32 timeout = EVENT_WAIT_FOREVER;
do {
rsi_wait_event(&coex_cb->coex_tx_thread.event, timeout);
rsi_reset_event(&coex_cb->coex_tx_thread.event);
rsi_coex_sched_tx_pkts(coex_cb);
} while (atomic_read(&coex_cb->coex_tx_thread.thread_done) == 0);
complete_and_exit(&coex_cb->coex_tx_thread.completion, 0);
}
开发者ID:AlexShiLucky,项目名称:linux,代码行数:15,代码来源:rsi_91x_coex.c
示例14: thread_write
static int thread_write(void *write_data)
{
private_data *data = (private_data *) write_data;
if (genstack_full(&stack)) // For debug added
{
pr_debug("Producer is going to sleep...\n");
if (wait_event_interruptible(wq_write, !genstack_full(&stack)))
return -ERESTART;
}
genstack_push(&stack, &data->write_data->user);
complete_and_exit(&data->on_exit, 0);
}
开发者ID:ReinerText,项目名称:SySo,代码行数:15,代码来源:buf_threaded.c
示例15: dhd_probe_thread
static int
dhd_probe_thread(void *data)
{
probe_info_t *pinfo = (probe_info_t *) data;
DAEMONIZE("dbus_probe_thread");
if (probe_cb) {
if (down_interruptible(&pinfo->sem) == 0)
disc_arg = probe_cb(probe_arg, "", 0, 0);
}
pinfo->dpc_pid = -1;
complete_and_exit(&pinfo->dpc_exited, 0);
}
开发者ID:cilynx,项目名称:dd-wrt,代码行数:15,代码来源:dbus_sdio_linux.c
示例16: ovc_scan_thread
static int ovc_scan_thread(void *data)
{
struct ovc *ovcinfo = NULL;
int state;
if (!u_notify) {
pr_err("%s u_notify is NULL\n", __func__);
return 0;
}
ovcinfo = &u_notify->ovc_info;
while (!kthread_should_stop()) {
wait_event_interruptible_timeout(ovcinfo->delay_wait,
ovcinfo->thread_remove, (ovcinfo->poll_period)*HZ);
if (ovcinfo->thread_remove)
break;
mutex_lock(&u_notify->ovc_info.ovc_lock);
if (ovcinfo->check_state
&& ovcinfo->data
&& ovcinfo->can_ovc) {
state = ovcinfo->check_state(data);
if (ovcinfo->prev_state != state) {
if (state == HNOTIFY_LOW) {
pr_err("%s overcurrent detected\n",
__func__);
host_state_notify(&u_notify->ndev,
NOTIFY_HOST_OVERCURRENT);
} else if (state == HNOTIFY_HIGH) {
pr_info("%s vbus draw detected\n",
__func__);
host_state_notify(&u_notify->ndev,
NOTIFY_HOST_NONE);
}
}
ovcinfo->prev_state = state;
}
mutex_unlock(&u_notify->ovc_info.ovc_lock);
if (!ovcinfo->can_ovc)
ovcinfo->thread_remove = 1;
}
pr_info("ovc_scan_thread exit\n");
complete_and_exit(&ovcinfo->scanning_done, 0);
return 0;
}
开发者ID:FyFyVy,项目名称:android_kernel_samsung_j13g,代码行数:47,代码来源:usb_notify.c
示例17: rtsx_polling_thread
static int rtsx_polling_thread(void *__dev)
{
struct rtsx_dev *dev = (struct rtsx_dev *)__dev;
struct rtsx_chip *chip = dev->chip;
struct Scsi_Host *host = rtsx_to_host(dev);
struct sd_info *sd_card = &(chip->sd_card);
struct xd_info *xd_card = &(chip->xd_card);
struct ms_info *ms_card = &(chip->ms_card);
sd_card->cleanup_counter = 0;
xd_card->cleanup_counter = 0;
ms_card->cleanup_counter = 0;
/* Wait until SCSI scan finished */
wait_timeout((delay_use + 5) * 1000);
for (;;) {
set_current_state(TASK_INTERRUPTIBLE);
schedule_timeout(POLLING_INTERVAL);
/* lock the device pointers */
mutex_lock(&(dev->dev_mutex));
/* if the device has disconnected, we are free to exit */
if (rtsx_chk_stat(chip, RTSX_STAT_DISCONNECT)) {
printk(KERN_INFO "-- rtsx-polling exiting\n");
mutex_unlock(&dev->dev_mutex);
break;
}
mutex_unlock(&dev->dev_mutex);
mspro_polling_format_status(chip);
/* lock the device pointers */
mutex_lock(&(dev->dev_mutex));
rtsx_polling_func(chip);
/* unlock the device pointers */
mutex_unlock(&dev->dev_mutex);
}
scsi_host_put(host);
complete_and_exit(&threads_gone, 0);
}
开发者ID:Neves4,项目名称:DatKernel,代码行数:47,代码来源:rtsx.c
示例18: moduleTestLoop
static void moduleTestLoop ( void ) {
int localCount = 0;
while (1) {
putABreakPointHere();
/* Waits 1 sec */
sleep_on_timeout(&wait,500);
PRINTF("moduleTest thread woke up. Global is %s !\n", globalData);
localCount++;
count += 2;
if (moduleTestExiting) {
PRINTF("localCount = %d; count = %d; moduleTest thread exiting!\n", localCount, count);
complete_and_exit(&evt_dead,0);
}
}
}
开发者ID:yanchao,项目名称:WTS,代码行数:17,代码来源:moduledebug.c
示例19: dbus_txq_thread
static int
dbus_txq_thread(void *data)
{
sdos_info_t *sdos_info = (sdos_info_t *)data;
DAEMONIZE("dbus_sdio_txq");
/* Run until signal received */
while (1) {
if (down_interruptible(&sdos_info->txq_sem) == 0)
dbus_sdio_txq_process(sdos_info->cbarg);
else
break;
}
complete_and_exit(&sdos_info->txq_exited, 0);
}
开发者ID:cilynx,项目名称:dd-wrt,代码行数:17,代码来源:dbus_sdio_linux.c
示例20: wlan_logging_thread
/**
* wlan_logging_thread() - The WLAN Logger thread
* @Arg - pointer to the HDD context
*
* This thread logs log message to App registered for the logs.
*/
static int wlan_logging_thread(void *Arg)
{
int ret_wait_status = 0;
int ret = 0;
set_user_nice(current, -2);
#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 8, 0))
daemonize("wlan_logging_thread");
#endif
while (!gwlan_logging.exit) {
ret_wait_status = wait_event_interruptible(
gwlan_logging.wait_queue,
(gwlan_logging.wakeEvent || gwlan_logging.exit));
gwlan_logging.wakeEvent = FALSE;
if (ret_wait_status == -ERESTARTSYS) {
pr_err("%s: wait_event_interruptible returned -ERESTARTSYS",
__func__);
break;
}
if (gwlan_logging.exit) {
pr_err("%s: Exiting the thread\n", __func__);
break;
}
if (INVALID_PID == gapp_pid) {
pr_err("%s: Invalid PID\n", __func__);
continue;
}
ret = send_filled_buffers_to_user();
if (-ENOMEM == ret) {
msleep(200);
}
}
pr_info("%s: Terminating\n", __func__);
complete_and_exit(&gwlan_logging.shutdown_comp, 0);
return 0;
}
开发者ID:LEPT-Development,项目名称:Android_kernel_lge_C50,代码行数:52,代码来源:wlan_logging_sock_svc.c
注:本文中的complete_and_exit函数示例由纯净天空整理自Github/MSDocs等源码及文档管理平台,相关代码片段筛选自各路编程大神贡献的开源项目,源码版权归原作者所有,传播和使用请参考对应项目的License;未经允许,请勿转载。 |
请发表评论