Annotation of embedaddon/curl/docs/examples/smooth-gtk-thread.c, revision 1.1
1.1 ! misho 1: /***************************************************************************
! 2: * _ _ ____ _
! 3: * Project ___| | | | _ \| |
! 4: * / __| | | | |_) | |
! 5: * | (__| |_| | _ <| |___
! 6: * \___|\___/|_| \_\_____|
! 7: *
! 8: * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
! 9: *
! 10: * This software is licensed as described in the file COPYING, which
! 11: * you should have received as part of this distribution. The terms
! 12: * are also available at https://curl.haxx.se/docs/copyright.html.
! 13: *
! 14: * You may opt to use, copy, modify, merge, publish, distribute and/or sell
! 15: * copies of the Software, and permit persons to whom the Software is
! 16: * furnished to do so, under the terms of the COPYING file.
! 17: *
! 18: * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
! 19: * KIND, either express or implied.
! 20: *
! 21: ***************************************************************************/
! 22: /* <DESC>
! 23: * A multi threaded application that uses a progress bar to show
! 24: * status. It uses Gtk+ to make a smooth pulse.
! 25: * </DESC>
! 26: */
! 27: /*
! 28: * Written by Jud Bishop after studying the other examples provided with
! 29: * libcurl.
! 30: *
! 31: * To compile (on a single line):
! 32: * gcc -ggdb `pkg-config --cflags --libs gtk+-2.0` -lcurl -lssl -lcrypto
! 33: * -lgthread-2.0 -dl smooth-gtk-thread.c -o smooth-gtk-thread
! 34: */
! 35:
! 36: #include <stdio.h>
! 37: #include <gtk/gtk.h>
! 38: #include <glib.h>
! 39: #include <unistd.h>
! 40: #include <pthread.h>
! 41:
! 42: #include <curl/curl.h>
! 43:
! 44: #define NUMT 4
! 45:
! 46: pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
! 47: int j = 0;
! 48: gint num_urls = 9; /* Just make sure this is less than urls[]*/
! 49: const char * const urls[]= {
! 50: "90022",
! 51: "90023",
! 52: "90024",
! 53: "90025",
! 54: "90026",
! 55: "90027",
! 56: "90028",
! 57: "90029",
! 58: "90030"
! 59: };
! 60:
! 61: size_t write_file(void *ptr, size_t size, size_t nmemb, FILE *stream)
! 62: {
! 63: /* printf("write_file\n"); */
! 64: return fwrite(ptr, size, nmemb, stream);
! 65: }
! 66:
! 67: /* https://weather.com/weather/today/l/46214?cc=*&dayf=5&unit=i */
! 68: void *pull_one_url(void *NaN)
! 69: {
! 70: /* Stop threads from entering unless j is incremented */
! 71: pthread_mutex_lock(&lock);
! 72: while(j < num_urls) {
! 73: CURL *curl;
! 74: gchar *http;
! 75:
! 76: printf("j = %d\n", j);
! 77:
! 78: http =
! 79: g_strdup_printf("xoap.weather.com/weather/local/%s?cc=*&dayf=5&unit=i\n",
! 80: urls[j]);
! 81:
! 82: printf("http %s", http);
! 83:
! 84: curl = curl_easy_init();
! 85: if(curl) {
! 86:
! 87: FILE *outfile = fopen(urls[j], "wb");
! 88:
! 89: /* Set the URL and transfer type */
! 90: curl_easy_setopt(curl, CURLOPT_URL, http);
! 91:
! 92: /* Write to the file */
! 93: curl_easy_setopt(curl, CURLOPT_WRITEDATA, outfile);
! 94: curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_file);
! 95:
! 96: j++; /* critical line */
! 97: pthread_mutex_unlock(&lock);
! 98:
! 99: curl_easy_perform(curl);
! 100:
! 101: fclose(outfile);
! 102: printf("fclose\n");
! 103:
! 104: curl_easy_cleanup(curl);
! 105: }
! 106: g_free(http);
! 107:
! 108: /* Adds more latency, testing the mutex.*/
! 109: sleep(1);
! 110:
! 111: } /* end while */
! 112: return NULL;
! 113: }
! 114:
! 115:
! 116: gboolean pulse_bar(gpointer data)
! 117: {
! 118: gdk_threads_enter();
! 119: gtk_progress_bar_pulse(GTK_PROGRESS_BAR (data));
! 120: gdk_threads_leave();
! 121:
! 122: /* Return true so the function will be called again;
! 123: * returning false removes this timeout function.
! 124: */
! 125: return TRUE;
! 126: }
! 127:
! 128: void *create_thread(void *progress_bar)
! 129: {
! 130: pthread_t tid[NUMT];
! 131: int i;
! 132:
! 133: /* Make sure I don't create more threads than urls. */
! 134: for(i = 0; i < NUMT && i < num_urls ; i++) {
! 135: int error = pthread_create(&tid[i],
! 136: NULL, /* default attributes please */
! 137: pull_one_url,
! 138: NULL);
! 139: if(0 != error)
! 140: fprintf(stderr, "Couldn't run thread number %d, errno %d\n", i, error);
! 141: else
! 142: fprintf(stderr, "Thread %d, gets %s\n", i, urls[i]);
! 143: }
! 144:
! 145: /* Wait for all threads to terminate. */
! 146: for(i = 0; i < NUMT && i < num_urls; i++) {
! 147: pthread_join(tid[i], NULL);
! 148: fprintf(stderr, "Thread %d terminated\n", i);
! 149: }
! 150:
! 151: /* This stops the pulsing if you have it turned on in the progress bar
! 152: section */
! 153: g_source_remove(GPOINTER_TO_INT(g_object_get_data(G_OBJECT(progress_bar),
! 154: "pulse_id")));
! 155:
! 156: /* This destroys the progress bar */
! 157: gtk_widget_destroy(progress_bar);
! 158:
! 159: /* [Un]Comment this out to kill the program rather than pushing close. */
! 160: /* gtk_main_quit(); */
! 161:
! 162:
! 163: return NULL;
! 164:
! 165: }
! 166:
! 167: static gboolean cb_delete(GtkWidget *window, gpointer data)
! 168: {
! 169: gtk_main_quit();
! 170: return FALSE;
! 171: }
! 172:
! 173: int main(int argc, char **argv)
! 174: {
! 175: GtkWidget *top_window, *outside_frame, *inside_frame, *progress_bar;
! 176:
! 177: /* Must initialize libcurl before any threads are started */
! 178: curl_global_init(CURL_GLOBAL_ALL);
! 179:
! 180: /* Init thread */
! 181: g_thread_init(NULL);
! 182: gdk_threads_init();
! 183: gdk_threads_enter();
! 184:
! 185: gtk_init(&argc, &argv);
! 186:
! 187: /* Base window */
! 188: top_window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
! 189:
! 190: /* Frame */
! 191: outside_frame = gtk_frame_new(NULL);
! 192: gtk_frame_set_shadow_type(GTK_FRAME(outside_frame), GTK_SHADOW_OUT);
! 193: gtk_container_add(GTK_CONTAINER(top_window), outside_frame);
! 194:
! 195: /* Frame */
! 196: inside_frame = gtk_frame_new(NULL);
! 197: gtk_frame_set_shadow_type(GTK_FRAME(inside_frame), GTK_SHADOW_IN);
! 198: gtk_container_set_border_width(GTK_CONTAINER(inside_frame), 5);
! 199: gtk_container_add(GTK_CONTAINER(outside_frame), inside_frame);
! 200:
! 201: /* Progress bar */
! 202: progress_bar = gtk_progress_bar_new();
! 203: gtk_progress_bar_pulse(GTK_PROGRESS_BAR (progress_bar));
! 204: /* Make uniform pulsing */
! 205: gint pulse_ref = g_timeout_add(300, pulse_bar, progress_bar);
! 206: g_object_set_data(G_OBJECT(progress_bar), "pulse_id",
! 207: GINT_TO_POINTER(pulse_ref));
! 208: gtk_container_add(GTK_CONTAINER(inside_frame), progress_bar);
! 209:
! 210: gtk_widget_show_all(top_window);
! 211: printf("gtk_widget_show_all\n");
! 212:
! 213: g_signal_connect(G_OBJECT (top_window), "delete-event",
! 214: G_CALLBACK(cb_delete), NULL);
! 215:
! 216: if(!g_thread_create(&create_thread, progress_bar, FALSE, NULL) != 0)
! 217: g_warning("can't create the thread");
! 218:
! 219: gtk_main();
! 220: gdk_threads_leave();
! 221: printf("gdk_threads_leave\n");
! 222:
! 223: return 0;
! 224: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>