int main (int argc, char *argv[]) { #if PORTABLE strcpy (dbinstalldir, argv[0]); char *e = dbinstalldir + strlen (dbinstalldir); while (e >= dbinstalldir && *e != '/') { e--; } *e = 0; #else strcpy (dbinstalldir, PREFIX); #endif #ifdef __linux__ signal (SIGSEGV, sigsegv_handler); #endif setlocale (LC_ALL, ""); setlocale (LC_NUMERIC, "C"); #ifdef ENABLE_NLS // fprintf (stderr, "enabling gettext support: package=" PACKAGE ", dir=" LOCALEDIR "...\n"); #if PORTABLE char localedir[PATH_MAX]; snprintf (localedir, sizeof (localedir), "%s/locale", dbinstalldir); bindtextdomain (PACKAGE, localedir); #else bindtextdomain (PACKAGE, LOCALEDIR); #endif bind_textdomain_codeset (PACKAGE, "UTF-8"); textdomain (PACKAGE); #endif int staticlink = 0; int portable = 0; #if STATICLINK staticlink = 1; #endif #if PORTABLE portable = 1; #endif fprintf (stderr, "starting deadbeef " VERSION "%s%s\n", staticlink ? " [static]" : "", portable ? " [portable]" : ""); srand (time (NULL)); #ifdef __linux__ prctl (PR_SET_NAME, "deadbeef-main", 0, 0, 0, 0); #endif #if PORTABLE_FULL if (snprintf (confdir, sizeof (confdir), "%s/config", dbinstalldir) > sizeof (confdir)) { fprintf (stderr, "fatal: too long install path %s\n", dbinstalldir); return -1; } strcpy (dbconfdir, confdir); #else char *homedir = getenv ("HOME"); if (!homedir) { fprintf (stderr, "unable to find home directory. stopping.\n"); return -1; } char *xdg_conf_dir = getenv ("XDG_CONFIG_HOME"); if (xdg_conf_dir) { if (snprintf (confdir, sizeof (confdir), "%s", xdg_conf_dir) > sizeof (confdir)) { fprintf (stderr, "fatal: XDG_CONFIG_HOME value is too long: %s\n", xdg_conf_dir); return -1; } } else { if (snprintf (confdir, sizeof (confdir), "%s/.config", homedir) > sizeof (confdir)) { fprintf (stderr, "fatal: HOME value is too long: %s\n", homedir); return -1; } } if (snprintf (dbconfdir, sizeof (dbconfdir), "%s/deadbeef", confdir) > sizeof (dbconfdir)) { fprintf (stderr, "fatal: out of memory while configuring\n"); return -1; } mkdir (confdir, 0755); #endif #if PORTABLE if (snprintf (dbdocdir, sizeof (dbdocdir), "%s/doc", dbinstalldir) > sizeof (dbdocdir)) { fprintf (stderr, "fatal: too long install path %s\n", dbinstalldir); return -1; } if (snprintf (dbplugindir, sizeof (dbplugindir), "%s/plugins", dbinstalldir) > sizeof (dbplugindir)) { fprintf (stderr, "fatal: too long install path %s\n", dbinstalldir); return -1; } if (snprintf (dbpixmapdir, sizeof (dbpixmapdir), "%s/pixmaps", dbinstalldir) > sizeof (dbpixmapdir)) { fprintf (stderr, "fatal: too long install path %s\n", dbinstalldir); return -1; } mkdir (dbplugindir, 0755); #else if (snprintf (dbdocdir, sizeof (dbdocdir), "%s", DOCDIR) > sizeof (dbdocdir)) { fprintf (stderr, "fatal: too long install path %s\n", dbinstalldir); return -1; } if (snprintf (dbplugindir, sizeof (dbplugindir), "%s/deadbeef", LIBDIR) > sizeof (dbplugindir)) { fprintf (stderr, "fatal: too long install path %s\n", dbinstalldir); return -1; } if (snprintf (dbpixmapdir, sizeof (dbpixmapdir), "%s/share/deadbeef/pixmaps", PREFIX) > sizeof (dbpixmapdir)) { fprintf (stderr, "fatal: too long install path %s\n", dbinstalldir); return -1; } #endif for (int i = 1; i < argc; i++) { // help, version and nowplaying are executed with any filter if (!strcmp (argv[i], "--help") || !strcmp (argv[i], "-h")) { print_help (); return 0; } else if (!strcmp (argv[i], "--version")) { fprintf (stdout, "DeaDBeeF " VERSION " Copyright © 2009-2011 Alexey Yakovenko\n"); return 0; } else if (!strcmp (argv[i], "--gui")) { strncpy (use_gui_plugin, argv[i], sizeof(use_gui_plugin) - 1); use_gui_plugin[sizeof(use_gui_plugin) - 1] = 0; } } trace ("installdir: %s\n", dbinstalldir); trace ("confdir: %s\n", confdir); trace ("docdir: %s\n", dbdocdir); trace ("plugindir: %s\n", dbplugindir); trace ("pixmapdir: %s\n", dbpixmapdir); mkdir (dbconfdir, 0755); int size = 0; char *cmdline = prepare_command_line (argc, argv, &size); // try to connect to remote player int s, len; struct sockaddr_un remote; if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) { perror("socket"); exit(1); } memset (&remote, 0, sizeof (remote)); remote.sun_family = AF_UNIX; #if USE_ABSTRACT_NAME memcpy (remote.sun_path, server_id, sizeof (server_id)); len = offsetof(struct sockaddr_un, sun_path) + sizeof (server_id)-1; #else char *socketdirenv = getenv ("DDB_SOCKET_DIR"); snprintf (remote.sun_path, sizeof (remote.sun_path), "%s/socket", socketdirenv ? socketdirenv : dbconfdir); len = offsetof(struct sockaddr_un, sun_path) + strlen (remote.sun_path); #endif if (connect(s, (struct sockaddr *)&remote, len) == 0) { // pass args to remote and exit if (send(s, cmdline, size, 0) == -1) { perror ("send"); exit (-1); } // end of message shutdown(s, SHUT_WR); int sz = -1; char *out = read_entire_message(s, &sz); if (sz == -1) { fprintf (stderr, "failed to pass args to remote!\n"); exit (-1); } else { // check if that's nowplaying response const char np[] = "nowplaying "; const char err[] = "error "; if (!strncmp (out, np, sizeof (np)-1)) { const char *prn = &out[sizeof (np)-1]; fwrite (prn, 1, strlen (prn), stdout); } else if (!strncmp (out, err, sizeof (err)-1)) { const char *prn = &out[sizeof (err)-1]; fwrite (prn, 1, strlen (prn), stderr); } else if (sz > 0 && out[0]) { fprintf (stderr, "%s\n", out); } } close (s); exit (0); } // else { // perror ("INFO: failed to connect to existing session:"); // } close(s); // become a server if (server_start () < 0) { exit (-1); } // hack: report nowplaying if (!strcmp (cmdline, "--nowplaying")) { char nothing[] = "nothing"; fwrite (nothing, 1, sizeof (nothing)-1, stdout); return 0; } pl_init (); conf_init (); conf_load (); // required by some plugins at startup if (use_gui_plugin[0]) { conf_set_str ("gui_plugin", use_gui_plugin); } conf_set_str ("deadbeef_version", VERSION); volume_set_db (conf_get_float ("playback.volume", 0)); // volume need to be initialized before plugins start messagepump_init (); // required to push messages while handling commandline if (plug_load_all ()) { // required to add files to playlist from commandline exit (-1); } pl_load_all (); plt_set_curr_idx (conf_get_int ("playlist.current", 0)); // execute server commands in local context int noloadpl = 0; if (argc > 1) { int res = server_exec_command_line (cmdline, size, NULL, 0); // some of the server commands ran on 1st instance should terminate it if (res == 2) { noloadpl = 1; } else if (res > 0) { exit (0); } else if (res < 0) { exit (-1); } } free (cmdline); #if 0 signal (SIGTERM, sigterm_handler); atexit (atexit_handler); // helps to save in simple cases #endif // start all subsystems messagepump_push (DB_EV_PLAYLISTCHANGED, 0, 0, 0); streamer_init (); plug_connect_all (); if (!noloadpl) { restore_resume_state (); } server_tid = thread_start (server_loop, NULL); // this runs in main thread (blocks right here) player_mainloop (); // terminate server and wait for completion if (server_tid) { server_terminate = 1; thread_join (server_tid); server_tid = 0; } // save config pl_save_all (); conf_save (); // delete legacy session file { char sessfile[1024]; // $HOME/.config/deadbeef/session if (snprintf (sessfile, sizeof (sessfile), "%s/deadbeef/session", confdir) < sizeof (sessfile)) { unlink (sessfile); } } // stop receiving messages from outside server_close (); // plugins might still hood references to playitems, // and query configuration in background // so unload everything 1st before final cleanup plug_disconnect_all (); plug_unload_all (); // at this point we can simply do exit(0), but let's clean up for debugging pl_free (); // may access conf_* conf_free (); messagepump_free (); plug_cleanup (); fprintf (stderr, "hej-hej!\n"); return 0; }
static void *thread_client_to_device(void *data) { socket_info_t* socket_info = (socket_info_t*)data; idevice_error_t res = IDEVICE_E_UNKNOWN_ERROR; int recv_len; int sent; char buffer[131072]; thread_t dtoc; debug("%s: started thread...\n", __func__); debug("%s: client_fd = %d\n", __func__, socket_info->client_fd); debug("%s: server_fd = %d\n", __func__, socket_info->server_fd); /* spawn server to client thread */ socket_info->stop_dtoc = 0; if (thread_create(&dtoc, thread_device_to_client, data) != 0) { fprintf(stderr, "Failed to start device to client thread...\n"); } while (!quit_flag && !socket_info->stop_ctod && socket_info->client_fd > 0 && socket_info->server_fd > 0) { debug("%s: receiving data from client...\n", __func__); /* attempt to read incoming data from client */ recv_len = socket_receive_timeout(socket_info->client_fd, buffer, sizeof(buffer), 0, 5000); /* any data received? */ if (recv_len <= 0) { if (recv_len == 0) { /* try again */ continue; } else { fprintf(stderr, "Receive failed: %s\n", strerror(errno)); break; } } else { /* forward data to device */ debug("%s: sending data to device...\n", __func__); res = idevice_connection_send(socket_info->device_connection, buffer, recv_len, (uint32_t*)&sent); if (sent < recv_len || res != IDEVICE_E_SUCCESS) { if (sent <= 0) { fprintf(stderr, "send failed: %s\n", strerror(errno)); break; } else { fprintf(stderr, "only sent %d from %d bytes\n", sent, recv_len); } } else { // sending succeeded, receive from device debug("%s: sent %d bytes to device\n", __func__, sent); } } } debug("%s: shutting down...\n", __func__); socket_shutdown(socket_info->client_fd, SHUT_RDWR); socket_close(socket_info->client_fd); socket_info->client_fd = -1; socket_info->stop_dtoc = 1; /* join other thread to allow it to stop */ thread_join(dtoc); return NULL; }
int main(int argc, char *argv[]) { /* Initialize our handles */ DB *dbp = NULL; DB_ENV *envp = NULL; thread_t writer_threads[NUMWRITERS]; int ch, i, ret, ret_t; u_int32_t env_flags; char *db_home_dir; /* Application name */ const char *prog_name = "txn_guide"; /* Database file name */ const char *file_name = "mydb.db"; /* Parse the command line arguments */ #ifdef _WIN32 db_home_dir = ".\\"; #else db_home_dir = "./"; #endif while ((ch = getopt(argc, argv, "h:")) != EOF) switch (ch) { case 'h': db_home_dir = optarg; break; case '?': default: return (usage()); } /* Create the environment */ ret = db_env_create(&envp, 0); if (ret != 0) { fprintf(stderr, "Error creating environment handle: %s\n", db_strerror(ret)); goto err; } /* * Indicate that we want db to perform lock detection internally. * Also indicate that the transaction with the fewest number of * write locks will receive the deadlock notification in * the event of a deadlock. */ ret = envp->set_lk_detect(envp, DB_LOCK_MINWRITE); if (ret != 0) { fprintf(stderr, "Error setting lock detect: %s\n", db_strerror(ret)); goto err; } env_flags = DB_CREATE | /* Create the environment if it does not exist */ DB_RECOVER | /* Run normal recovery. */ DB_INIT_LOCK | /* Initialize the locking subsystem */ DB_INIT_LOG | /* Initialize the logging subsystem */ DB_INIT_TXN | /* Initialize the transactional subsystem. This * also turns on logging. */ DB_INIT_MPOOL | /* Initialize the memory pool (in-memory cache) */ DB_THREAD; /* Cause the environment to be free-threaded */ /* Now actually open the environment */ ret = envp->open(envp, db_home_dir, env_flags, 0); if (ret != 0) { fprintf(stderr, "Error opening environment: %s\n", db_strerror(ret)); goto err; } /* * If we had utility threads (for running checkpoints or * deadlock detection, for example) we would spawn those * here. However, for a simple example such as this, * that is not required. */ /* Open the database */ ret = open_db(&dbp, prog_name, file_name, envp, DB_DUPSORT); if (ret != 0) goto err; /* Initialize a mutex. Used to help provide thread ids. */ (void)mutex_init(&thread_num_lock, NULL); /* Start the writer threads. */ for (i = 0; i < NUMWRITERS; i++) (void)thread_create( &writer_threads[i], NULL, writer_thread, (void *)dbp); /* Join the writers */ for (i = 0; i < NUMWRITERS; i++) (void)thread_join(writer_threads[i], NULL); err: /* Close our database handle, if it was opened. */ if (dbp != NULL) { ret_t = dbp->close(dbp, 0); if (ret_t != 0) { fprintf(stderr, "%s database close failed: %s\n", file_name, db_strerror(ret_t)); ret = ret_t; } } /* Close our environment, if it was opened. */ if (envp != NULL) { ret_t = envp->close(envp, 0); if (ret_t != 0) { fprintf(stderr, "environment close failed: %s\n", db_strerror(ret_t)); ret = ret_t; } } /* Final status message and return. */ printf("I'm all done.\n"); return (ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE); }
int crawl(char *start_url, int download_workers, int parse_workers, int queue_size, char *(*_fetch_fn)(char *url), void (*_edge_fn)(char *from, char *to)) { int i; bounded_buffer_t url_queue; unbounded_buffer_t page_queue; hashset_t url_set; bounded_buffer_init(&url_queue, queue_size); unbounded_buffer_init(&page_queue); hashset_init(&url_set, HASHSET_BUCKETS); bounded_buffer_put(&url_queue, (void *)str_duplicate(start_url)); mutex_t done_mutex; cond_t done_cond; mutex_init(&done_mutex); cond_init(&done_cond); struct input_args in_args; in_args.url_queue = &url_queue; in_args.page_queue = &page_queue; in_args.url_set = &url_set; in_args.fetch = _fetch_fn; in_args.edge = _edge_fn; in_args.done_mutex = &done_mutex; in_args.done_cond = &done_cond; thread_t downloaders[download_workers]; thread_t parsers[parse_workers]; for (i = 0; i < download_workers; i++) thread_create(&downloaders[i], downloader, (void *)&in_args); for (i = 0; i < parse_workers; i++) thread_create(&parsers[i], parser, (void *)&in_args); while (1) { mutex_lock(&done_mutex); mutex_lock(&url_queue.mutex); mutex_lock(&url_queue.worker_mutex); mutex_lock(&page_queue.mutex); mutex_lock(&page_queue.worker_mutex); if (url_queue.count == 0 && url_queue.workers == 0 && page_queue.count == 0 && page_queue.workers == 0) { url_queue.done = 1; page_queue.done = 1; cond_broadcast(&url_queue.empty); cond_broadcast(&url_queue.fill); cond_broadcast(&page_queue.fill); mutex_unlock(&url_queue.mutex); mutex_unlock(&url_queue.worker_mutex); mutex_unlock(&page_queue.mutex); mutex_unlock(&page_queue.worker_mutex); mutex_unlock(&done_mutex); break; } else { mutex_unlock(&url_queue.mutex); mutex_unlock(&url_queue.worker_mutex); mutex_unlock(&page_queue.mutex); mutex_unlock(&page_queue.worker_mutex); cond_wait(&done_cond, &done_mutex); mutex_unlock(&done_mutex); } } for (i = 0; i < download_workers; i++) thread_join(downloaders[i], NULL); for (i = 0; i < parse_workers; i++) thread_join(parsers[i], NULL); bounded_buffer_destroy(&url_queue); unbounded_buffer_destroy(&page_queue); hashset_destroy(&url_set); return 0; }
int TestKeyExistErrorReturn(CuTest *ct) { DB *pdbp; DB *sdbp; DB_ENV *dbenv; const char *sec_db_file = "secondary.db"; const char *pri_db_file = "primary.db"; const char *env_dir = "TESTDIR"; int i; thread_t writer_threads[NUMWRITERS]; u_int32_t db_flags, env_flags; pdbp = sdbp = NULL; dbenv = NULL; db_flags = DB_CREATE | DB_AUTO_COMMIT | DB_READ_UNCOMMITTED; env_flags = DB_CREATE | DB_RECOVER | DB_INIT_LOCK | DB_INIT_LOG | DB_INIT_MPOOL | DB_INIT_TXN | DB_THREAD; TestEnvConfigTestSetup(ct); CuAssert(ct, "db_env_create", db_env_create(&dbenv, 0) == 0); dbenv->set_errfile(dbenv, stderr); dbenv->set_errpfx(dbenv, "TestKeyExistErrorReturn"); /* Run deadlock detector on every lock conflict. */ CuAssert(ct, "dbenv->set_lk_detect", dbenv->set_lk_detect(dbenv, DB_LOCK_MINWRITE) == 0); CuAssert(ct, "dbenv->open", dbenv->open(dbenv, env_dir, env_flags, 0) == 0); CuAssert(ct, "db_create", db_create(&pdbp, dbenv, 0) == 0); CuAssert(ct, "pdbp->open", pdbp->open(pdbp, NULL, pri_db_file, NULL, DB_BTREE, db_flags, 0) == 0); CuAssert(ct, "db_create", db_create(&sdbp, dbenv, 0) == 0); CuAssert(ct, "sdbp->set_flags", sdbp->set_flags(sdbp, DB_DUPSORT) == 0); CuAssert(ct, "sdbp->open", sdbp->open(sdbp, NULL, sec_db_file, NULL, DB_BTREE, db_flags, 0) == 0); CuAssert(ct, "DB->associate", pdbp->associate(pdbp, NULL, sdbp, assoc_callback, DB_AUTO_COMMIT) == 0); /* Initialize a mutex. Used to help provide thread ids. */ (void)mutex_init(&thread_num_lock, NULL); for (i = 0; i < NUMWRITERS; ++i) (void)thread_create(&writer_threads[i], NULL, writer_thread, (void *)pdbp); for (i = 0; i < NUMWRITERS; ++i) (void)thread_join(writer_threads[i], NULL); if (sdbp != NULL) CuAssert(ct, "sdbp->close", sdbp->close(sdbp, 0) == 0); if (pdbp != NULL) CuAssert(ct, "pdbp->close", pdbp->close(pdbp, 0) == 0); if (dbenv != NULL) CuAssert(ct, "dbenv->close", dbenv->close(dbenv, 0) == 0); TestEnvConfigTestTeardown(ct); return (EXIT_SUCCESS); }
int video_generator_clear(video_generator* g) { /* stop the audio thread if it's running. */ if (NULL != g->audio_thread) { mutex_lock(&g->audio_mutex); g->audio_thread_must_stop = 1; mutex_unlock(&g->audio_mutex); thread_join(g->audio_thread); g->audio_thread = NULL; /* free the audio buffer. */ if (NULL != g->audio_buffer) { free(g->audio_buffer); g->audio_buffer = NULL; } } if (!g) { return -1; } if (!g->width) { return -2; } if (!g->height) { return -3; } if (g->y) { free(g->y); } g->y = NULL; g->u = NULL; g->u = NULL; g->width = 0; g->height = 0; g->frame = 0; g->step = 0.0; g->perc = 0.0; g->fps = 0.0; g->ybytes = 0; g->ubytes = 0; g->vbytes = 0; g->nbytes = 0; g->strides[0] = 0; g->strides[1] = 0; g->strides[2] = 0; g->planes[0] = NULL; g->planes[1] = NULL; g->planes[2] = NULL; g->audio_nchannels = 0; g->audio_nseconds = 0; g->audio_samplerate = 0; g->audio_bip_frequency = 0; g->audio_bop_frequency = 0; g->audio_bip_millis = 0; g->audio_bop_millis = 0; g->audio_nbytes = 0; g->audio_callback = NULL; return 0; }