Return to smooth-gtk-thread.c CVS log | Up to [ELWIX - Embedded LightWeight unIX -] / embedaddon / curl / docs / examples |
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: }