📄 sendsms.c
字号:
/* * gsms - threading code - calles the plugins * * Authors: Michael Jochum <e9725005@stud3.tuwien.ac.at> * * TODO: * * Fixes: * * For license terms, see the file COPYING in the project directory. */#include <gnome.h>#include <stdlib.h>#include <unistd.h>#include <stdio.h>#include <pthread.h>#include <semaphore.h>#include <plugin.h>#include "sendsms.h"typedef struct { GSmsMessage *message; pthread_t tid; sem_t *sem1, *sem2;} ThreadData;typedef struct { GSList *messages; GSmsSentFunc callback; gint maxthreads; GList *threads; pthread_t tid; sem_t sem1, sem2;} MainThreadData;static void thread_send(gpointer thread_data);// static void thread_send_all_cancel(gpointer data);static void thread_send_all_wait(MainThreadData *td);static void thread_send_all(gpointer data);static voidthread_send(gpointer thread_data){ ThreadData *data = thread_data; GSmsMessage *msg = data->message; gint sent = -1;#if 1 PluginData *pd; GList *plugins; if( (plugins = plugin_find(msg->num)) == NULL) { g_log("MAIN", G_LOG_LEVEL_INFO, _("Could not find provider for number %s"), msg->num); } else { while(sent == -1 && plugins != NULL) { pd = plugins->data; if (pd->send_sms(pd, msg->text, msg->num) < 0) { g_log("MAIN", G_LOG_LEVEL_INFO, _("Message to %s could not be sent\n"), msg->num); } else { g_log("MAIN", G_LOG_LEVEL_INFO, _("Message to %s send sucessfully\n"), msg->num); sent = 1; break; } plugins = g_list_next(plugins); } g_list_free(plugins); }#else int sec; sec = 1+(int) (10.0*rand()/(RAND_MAX+1.0)); sleep(sec); /* return 1 or -1 */ sent = ((int) (2.0*rand()/(RAND_MAX+1.0))) * 2 - 1 ;#endif sem_wait(data->sem1); msg->sent = sent; sem_post(data->sem2); pthread_exit(NULL);}static voidthread_send_all_cancel(gpointer main_thread_data){ MainThreadData *td = main_thread_data; GList *entry; ThreadData *data; /* In Linux we can use the implementation bug of pthreads to cancel the running plugins because system calls like read, write, connect, ... will fail and return EINTR - because EINTR is not handled the functions in libsms will exit with an error code and the plugin terminates. If we are not on Linux we wait for the remaining threads to finish. */ entry = td->threads; while(entry != NULL) { data = entry->data; pthread_cancel(data->tid); entry = g_list_next(entry); } /* join all child threads */ entry = td->threads; while(entry != NULL) { GList *tmp; data = entry->data; pthread_join(data->tid, NULL); g_free(data); tmp=entry; entry = g_list_next(entry); td->threads = g_list_remove_link (td->threads, tmp); g_list_free_1(tmp); } sem_destroy(& td->sem1); sem_destroy(& td->sem2);}static voidthread_send_all_wait(MainThreadData *td) { GList *entry; sem_post(& td->sem1); sem_wait(& td->sem2); entry = td->threads; while(entry != NULL) { ThreadData *data; GList *e = entry; entry = g_list_next(entry); data = e->data; if(data->message->sent != 0) { td->threads = g_list_remove_link (td->threads, e); g_list_free_1(e); if(td->callback != NULL) td->callback(data->message, NULL); pthread_join(data->tid, NULL); g_free(data); return; } }}static void thread_send_all(gpointer data){ MainThreadData *td = data; GSList *entry; sem_init(& td->sem1, 0, 0); sem_init(& td->sem2, 0, 0); pthread_cleanup_push(thread_send_all_cancel , td); entry = td->messages; while(entry != NULL) { if(g_list_length(td->threads) < td->maxthreads) { ThreadData *data; data = g_new(ThreadData, 1); td->threads = g_list_append(td->threads, data); data->message = entry->data; data->sem1 = & td->sem1; data->sem2 = & td->sem2; if (pthread_create(& data->tid, NULL, (gpointer) &thread_send, (gpointer) data) != 0) { g_log(NULL, G_LOG_LEVEL_ERROR, "Could not create thread"); /* TODO error handling */ } entry = g_slist_next(entry); } else { thread_send_all_wait(td); } } while(g_list_length(td->threads) > 0) thread_send_all_wait(td); if(td->callback != NULL) { td->callback(NULL, td->messages); } sem_destroy(& td->sem1); sem_destroy(& td->sem2); pthread_cleanup_pop(0); if(td->callback != NULL) { g_free(td); } pthread_exit(NULL);}gpointer send_sms(GSList *messages, gint maxthreads, GSmsSentFunc callback){ MainThreadData *td; g_return_val_if_fail (messages != NULL, NULL); g_return_val_if_fail (maxthreads > 0, NULL); td = g_new0(MainThreadData, 1); td->maxthreads = maxthreads; td->callback = callback; td->messages = messages; if (pthread_create(& td->tid, NULL, (gpointer) &thread_send_all, (gpointer) td) != 0) { g_log(NULL, G_LOG_LEVEL_ERROR, "Could not create thread"); g_free(td); return NULL; } return td;}GSList *send_sms_end(gpointer handle, gboolean abort){ MainThreadData *td = handle; GSList *messages = td->messages; g_return_val_if_fail (handle != NULL, NULL); if(abort) pthread_cancel(td->tid); pthread_join(td->tid, NULL); g_free(td); return messages;}#if 0int main(void){ GSmsMessage *m; GSList *messages = NULL; int i; for(i = 0; i < 50; i++) { m = g_new0(GSmsMessage,1); m->text = g_strdup_printf("This is message %d/50", i+1); m->num = g_strdup_printf("+43%d", i); messages = g_slist_append(messages, m); } send_sms(messages, 4, NULL); sleep(600); return 0;}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -