/** 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);
}
示例#3
0
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);
}
示例#6
0
/* 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
}
示例#7
0
文件: job.c 项目: dun/munge
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;
}
示例#8
0
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);
}