/** Set the event list for a new IO instance * * @param[in] li the listener * @param[in] el the event list * @param[in] nr context from the network side */ static void mod_event_list_set(fr_listen_t *li, fr_event_list_t *el, UNUSED void *nr) { proto_detail_file_t const *inst = talloc_get_type_abort_const(li->app_io_instance, proto_detail_file_t); proto_detail_file_thread_t *thread = talloc_get_type_abort(li->thread_instance, proto_detail_file_thread_t); struct timeval when; thread->el = el; if (inst->immediate) { work_init(thread); return; } /* * Delay for a bit, before reading the detail files. * This gives the server time to call * rad_suid_down_permanent(), and for /proc/PID to * therefore change permissions, so that libkqueue can * read it. */ gettimeofday(&when, NULL); when.tv_sec +=1; if (fr_event_timer_insert(thread, thread->el, &thread->ev, &when, work_retry_timer, thread) < 0) { ERROR("Failed inserting poll timer for %s", thread->filename_work); } }
static void mod_vnode_delete(fr_event_list_t *el, int fd, UNUSED int fflags, void *ctx) { proto_detail_file_thread_t *thread = talloc_get_type_abort(ctx, proto_detail_file_thread_t); proto_detail_file_t const *inst = thread->inst; DEBUG("proto_detail (%s): Deleted %s", thread->name, inst->filename_work); /* * Silently ignore notifications from the directory. We * didn't ask for them, but libkqueue delivers them to * us. */ if (fd == thread->fd) return; if (fd != thread->vnode_fd) { ERROR("Received DELETE for FD %d, when we were expecting one on FD %d - ignoring it", fd, thread->vnode_fd); return; } if (fr_event_fd_delete(el, fd, FR_EVENT_FILTER_VNODE) < 0) { PERROR("Failed removing DELETE callback after deletion"); } close(fd); thread->vnode_fd = -1; /* * Re-initialize the state machine. * * Note that a "delete" may be the result of an atomic * "move", which both deletes the old file, and creates * the new one. */ work_init(thread); }
int main(int argc, char **argv) { struct sigaction sig_stop; struct sigaction sig_time; _main = main_init(argc, argv); _log = log_init(); _main->conf = conf_init(argc, argv); _main->work = work_init(); _main->tcp = tcp_init(); _main->node = node_init(); _main->mime = mime_init(); /* Check configuration */ conf_print(); /* Catch SIG INT */ unix_signal(&sig_stop, &sig_time); /* Fork daemon */ unix_fork(log_console(_log)); /* Increase limits */ unix_limits(_main->conf->cores, CONF_EPOLL_MAX_EVENTS); /* Load mime types */ mime_load(); mime_hash(); /* Prepare TCP daemon */ tcp_start(); /* Drop privileges */ unix_dropuid0(); /* Start worker threads */ work_start(); /* Stop worker threads */ work_stop(); /* Stop TCP daemon */ tcp_stop(); mime_free(); node_free(); tcp_free(); work_free(); conf_free(); log_free(_log); main_free(); return 0; }
/** Set the event list for a new IO instance * * @param[in] li the listener * @param[in] el the event list * @param[in] nr context from the network side */ static void mod_event_list_set(fr_listen_t *li, fr_event_list_t *el, UNUSED void *nr) { proto_detail_file_thread_t *thread = talloc_get_type_abort(li->thread_instance, proto_detail_file_thread_t); #ifdef __linux__ struct timeval when; #endif thread->el = el; /* * Initialize the work state machine. */ #ifndef __linux__ work_init(thread); #else /* * We're not changing UID, etc. Start processing the * detail files now. */ if (!main_config->allow_core_dumps) { work_init(thread); return; } /* * Delay for a bit, before reading the detail files. * This gives the server time to call * rad_suid_down_permanent(), and for /proc/PID to * therefore change permissions, so that libkqueue can * read it. */ gettimeofday(&when, NULL); when.tv_sec +=1; if (fr_event_timer_insert(thread, thread->el, &thread->ev, &when, work_retry_timer, thread) < 0) { ERROR("Failed inserting poll timer for %s", thread->filename_work); } #endif }
static void mod_vnode_extend(fr_listen_t *li, UNUSED uint32_t fflags) { proto_detail_file_thread_t *thread = talloc_get_type_abort(li->thread_instance, proto_detail_file_thread_t); bool has_worker = false; pthread_mutex_lock(&thread->worker_mutex); has_worker = (thread->num_workers != 0); pthread_mutex_unlock(&thread->worker_mutex); if (has_worker) return; if (thread->ev) fr_event_timer_delete(thread->el, &thread->ev); work_init(thread); }
/* Main routine, called by client to do a sort. */ void quick_sort(float *data, int n) { if (quick_sort_workpile == NULL) { int n_threads = 6; quick_sort_workpile = work_init(2 << DEFER_DEPTH, quick_sort_worker, n_threads); assert(quick_sort_workpile != NULL); } quick_sort_aux(data, n, 0, quick_sort_workpile, FALSE); /* Wait for all work to finish */ work_wait(quick_sort_workpile); #ifdef QUICK_DEBUG printf( "== Quicksort: done sorting\n" ); #endif }
void job_accept (conf_t conf) { work_p w; m_msg_t m; int sd; assert (conf != NULL); assert (conf->ld >= 0); if (!(w = work_init ((work_func_t) _job_exec, conf->nthreads))) { log_errno (EMUNGE_SNAFU, LOG_ERR, "Failed to create %d work thread%s", conf->nthreads, ((conf->nthreads > 1) ? "s" : "")); } log_msg (LOG_INFO, "Created %d work thread%s", conf->nthreads, ((conf->nthreads > 1) ? "s" : "")); while (!done) { if ((sd = accept (conf->ld, NULL, NULL)) < 0) { switch (errno) { case ECONNABORTED: case EINTR: continue; case EMFILE: case ENFILE: case ENOBUFS: case ENOMEM: log_msg (LOG_INFO, "Suspended new connections while processing backlog"); work_wait (w); continue; default: log_errno (EMUNGE_SNAFU, LOG_ERR, "Failed to accept connection"); break; } } /* With fd_timed_read_n(), a poll() is performed before any read() * in order to provide timeouts and ensure the read() won't block. * As such, it shouldn't be necessary to set the client socket as * non-blocking. However according to the Linux poll(2) and * select(2) manpages, spurious readiness notifications can occur. * poll()/select() may report a socket as ready for reading while * the subsequent read() blocks. This could happen when data has * arrived, but upon examination is discarded due to an invalid * checksum. To protect against this, the client socket is set * non-blocking and EAGAIN is handled appropriately. */ if (fd_set_nonblocking (sd) < 0) { close (sd); log_msg (LOG_WARNING, "Failed to set nonblocking client socket: %s", strerror (errno)); } else if (m_msg_create (&m) != EMUNGE_SUCCESS) { close (sd); log_msg (LOG_WARNING, "Failed to create client request"); } else if (m_msg_bind (m, sd) != EMUNGE_SUCCESS) { m_msg_destroy (m); log_msg (LOG_WARNING, "Failed to bind socket for client request"); } else if (work_queue (w, m) < 0) { m_msg_destroy (m); log_msg (LOG_WARNING, "Failed to queue client request"); } } log_msg (LOG_NOTICE, "Exiting on signal=%d", done); work_fini (w, 1); return; }
static int pmic_battery_probe(struct platform_device *pdev) { int retval = 0; struct mc13892_dev_info *di; pmic_event_callback_t bat_event_callback; pmic_version_t pmic_version; //printk("%s %s %d \n",__FILE__,__func__,__LINE__); /* Only apply battery driver for MC13892 V2.0 due to ENGR108085 */ pmic_version = pmic_get_version(); if (pmic_version.revision < 20) { pr_debug("Battery driver is only applied for MC13892 V2.0\n"); return -1; } if (machine_is_mx50_arm2()) { pr_debug("mc13892 charger is not used for this platform\n"); return -1; } di = kzalloc(sizeof(*di), GFP_KERNEL); if (!di) { retval = -ENOMEM; goto di_alloc_failed; } di->init_charge = -1; platform_set_drvdata(pdev, di); di->charger.name = "mc13892_charger"; di->charger.type = POWER_SUPPLY_TYPE_MAINS; di->charger.properties = mc13892_charger_props; di->charger.num_properties = ARRAY_SIZE(mc13892_charger_props); di->charger.get_property = mc13892_charger_get_property; retval = power_supply_register(&pdev->dev, &di->charger); if (retval) { dev_err(di->dev, "failed to register charger\n"); goto charger_failed; } INIT_DELAYED_WORK(&di->monitor_work, mc13892_battery_work); di->monitor_wqueue = create_singlethread_workqueue(dev_name(&pdev->dev)); if (!di->monitor_wqueue) { retval = -ESRCH; goto workqueue_failed; } queue_delayed_work(di->monitor_wqueue, &di->monitor_work, HZ * 10); //queue_delayed_work(di->monitor_wqueue, &di->monitor_work, msecs_to_jiffies(10000)); pmic_stop_coulomb_counter(); pmic_calibrate_coulomb_counter(); //for get correct voltage on the battery when booting with external power. //chg_thread will change it, when next work (chg_work) is start. pmic_set_chg_current(0); INIT_DELAYED_WORK(&di->calc_capacity,mc13892_compute_battery_capacity_from_CC); queue_delayed_work(di->monitor_wqueue, &di->calc_capacity, 0); INIT_DELAYED_WORK(&chg_work, chg_thread); chg_wq = create_singlethread_workqueue("mxc_chg"); if (!chg_wq) { retval = -ESRCH; goto workqueue_failed; } queue_delayed_work(chg_wq, &chg_work, HZ); di->dev = &pdev->dev; di->bat.name = "mc13892_bat"; di->bat.type = POWER_SUPPLY_TYPE_BATTERY; di->bat.properties = mc13892_battery_props; di->bat.num_properties = ARRAY_SIZE(mc13892_battery_props); di->bat.get_property = mc13892_battery_get_property; di->bat.use_for_apm = 1; di->battery_status = POWER_SUPPLY_STATUS_UNKNOWN; //di->battery_status = POWER_SUPPLY_STATUS_DISCHARGING; retval = power_supply_register(&pdev->dev, &di->bat); if (retval) { dev_err(di->dev, "failed to register battery\n"); goto batt_failed; } bat_event_callback.func = charger_online_event_callback; bat_event_callback.param = (void *) di; pmic_event_subscribe(EVENT_CHGDETI, bat_event_callback); retval = sysfs_create_file(&pdev->dev.kobj, &dev_attr_enable.attr); if (retval) { printk(KERN_ERR "Battery: Unable to register sysdev entry for Battery"); goto workqueue_failed; } chg_wa_is_active = 1; chg_wa_timer = 0; disable_chg_timer = 0; #if defined(PMIC_MC13892_BATTERY_WORK) work_init(); #endif goto success; workqueue_failed: power_supply_unregister(&di->charger); charger_failed: power_supply_unregister(&di->bat); batt_failed: kfree(di); di_alloc_failed: success: dev_dbg(di->dev, "%s battery probed!\n", __func__); return retval; return 0; }
/* * Start polling again after a timeout. */ static void work_retry_timer(UNUSED fr_event_list_t *el, UNUSED struct timeval *now, void *uctx) { proto_detail_file_thread_t *thread = talloc_get_type_abort(uctx, proto_detail_file_thread_t); work_init(thread); }