Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
home:Lachu:SystemServices
Lachu-PackageKit
0013-Add-field-in-job-pointed-if-task-is-done-s...
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File 0013-Add-field-in-job-pointed-if-task-is-done-so-backend-.patch of Package Lachu-PackageKit
From 5f6820f58620a8285ee6f7b9c0d738de655d7e44 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C5=82awomir=20Lach?= <slawek@lach.art.pl> Date: Tue, 13 Oct 2020 18:10:36 +0200 Subject: [PATCH 13/46] - Add field in job pointed if task is done, so backend can do many stuff - Do not free job data if backend didn't comply task - Add communication between packagekit zypp backend and dependency solving helper - Change semantics of communication protocol (see above), so we send or not null bytes pointing string end - Change get_record (in helper) routine, so we work well with pipes - Change code responsible for displaying message, so we avoid many bugs --- backends/zypp/pk-backend-zypp.cpp | 306 +++++++++++++++++++++----- helpers/dependency-solving-helper.cpp | 220 ++++++++++++++---- src/pk-backend-job.c | 23 +- src/pk-backend-job.h | 7 +- 4 files changed, 447 insertions(+), 109 deletions(-) diff --git a/backends/zypp/pk-backend-zypp.cpp b/backends/zypp/pk-backend-zypp.cpp index 4d7a121d6..bedfeb51d 100644 --- a/backends/zypp/pk-backend-zypp.cpp +++ b/backends/zypp/pk-backend-zypp.cpp @@ -117,6 +117,15 @@ struct backend_job_private { std::list<struct problem> problems; + struct msg_proc_helper *msg_proc_helper; + + PkBackendJob *job; + gint input_id; + int input; + int ouput; + + int output; + }; typedef enum { @@ -1483,7 +1492,12 @@ zypp_backend_pool_item_notify (PkBackendJob *job, #include <libxslt/xsltInternals.h> #include <libxslt/transform.h> #include <libxslt/xsltutils.h> - +struct reader_info { + char *buffer; + int curr_old; + int loaded; + int buff_len; +} ; struct msg_proc_helper { ResolverProblemList::iterator it; @@ -1491,6 +1505,10 @@ struct msg_proc_helper { ResolverProblemList problems; ProblemSolutionList *solution_list; std::list<struct problem> problems2; + char *path_to_cache; + + struct reader_info reader_info; + }; static std::string get_full_resolution_text(zypp::ProblemSolution& item) @@ -2110,40 +2128,159 @@ static void save_transaction_to_cache(const char *type, const char *file, struct } close(fd); } -gboolean -dependency_handle_selection(GIOChannel *source, - GIOCondition condition, - gpointer data) + +static char +*get_record2(int fd, struct reader_info *info) { - #if 0 - ProblemSolutionList::const_iterator it2; - ResolverProblemList::iterator it = helper->problems.begin(); - std::advance( - it, - problem_number); - ResolverProblem problem = **it; + int count = 0; + bool done = false; + int curr = 0; + int curr2 = info->curr_old; + + + while (info->loaded >= curr2 + 1) { - it2 = problem.solutions().begin(); - std::advance( - it2, - solution_number); - ProblemSolution solution = **it2; + + if ('\0' == info->buffer[curr2]) { - struct problem prob; - prob.kind = problem.description(); - //prob.solutions = - prob.selected = get_full_resolution_text(solution); + curr = info->curr_old ; + info->curr_old = curr2 + 1; + return &info->buffer[curr]; + } + + ++curr2; + } + + info->buff_len += 512; + info->buffer = (char*)realloc(info->buffer, info->buff_len); + + if (NULL == info->buffer) { + + puts("HERE - BAD"); + return NULL; + } + + while ((count = read(fd, &info->buffer[info->loaded], info->buff_len - 1 - info->loaded)) > 0 || (errno == EAGAIN && info->loaded < info->curr_old)) { + + puts("BAD"); + curr = info->loaded; + info->loaded += count; + while ('\0' != info->buffer[curr] && curr < info->loaded) { - it2 = problem.solutions().begin(); + ++curr; + } + + if (curr < info->loaded && '\0' == info->buffer[curr]) { - for (; it2 != problem.solutions().end(); ++it2) { - - prob.solutions.push_back(get_full_resolution_text(**it2)); + done = true; + break; + } + + info->buff_len += 512; + info->buffer = (char*)realloc(info->buffer, info->buff_len); + + if (NULL == info->buffer) { + + count = 0; + break; + } + }; + + if (!done && 0 > count && info->loaded >= info->curr_old) { + + perror("Error while read from pipe"); + free(info->buffer); + close(fd); + return NULL; + } + + info->buffer[info->loaded] = '\0'; + + curr2 = info->curr_old; + info->curr_old = curr + 1; + return &info->buffer[curr2]; + } +static gboolean +dependency_handle_selection(GIOChannel *source, + GIOCondition condition, + gpointer data) +{ + #if 0 helper->problems2.push_back(prob); #endif +struct backend_job_private *msg_proc = (struct backend_job_private*) data; + int fd = g_io_channel_unix_get_fd (source); + + //fcntl(fd, F_SETFL, O_NONBLOCK); + int flags = fcntl(fd, F_GETFL, 0); + fcntl(fd, F_SETFL, flags | O_NONBLOCK); + char *buffer ; + puts("YES"); + while (buffer = get_record2(fd, &msg_proc->msg_proc_helper->reader_info)) { + puts(buffer); + puts("\n"); + if (0 == strncmp("ERR:", buffer, sizeof("ERR:") - 1)) { + + + } + else if (0 == strncmp("SELECTION:", buffer, sizeof("SELECTION:") - 1)) { + + puts("OKI"); + buffer = get_record2(fd, &msg_proc->msg_proc_helper->reader_info); + + puts(buffer); + char *problem_str = strchr(buffer, ':'); + if (NULL == problem_str) { + + puts("BAD222"); + return FALSE; + } + + char *solution_str = strchr(problem_str, ':'); + + if (NULL == solution_str) { + + puts("BAD333"); + return FALSE; + } + + int solution_number = atoi(solution_str); + int problem_number = atoi(problem_str); + + + ProblemSolutionList::const_iterator it2; + ResolverProblemList::iterator it = msg_proc->msg_proc_helper->problems.begin(); + std::advance( + it, + problem_number); + ResolverProblem problem = **it; + + it2 = problem.solutions().begin(); + std::advance( + it2, + solution_number); + ProblemSolution solution = **it2; + msg_proc->msg_proc_helper->solution_list->push_back(*it2); + puts("OKI2"); + } + else if (0 == strncmp("STOP", buffer, sizeof("STOP") - 1)) { + + + } + else if (0 == strncmp("DONE!", buffer, sizeof("DONE!") - 1)) { + add_resolution_to_zypp(msg_proc->msg_proc_helper); + /* Save resolution to file */ + save_transaction_to_cache("Install", msg_proc->msg_proc_helper->path_to_cache, msg_proc->msg_proc_helper, + msg_proc->to_install, msg_proc->to_remove); + + puts("END"); + pk_backend_job_thread_setup(msg_proc->job->helper); + + } + } return TRUE; } @@ -2163,14 +2300,13 @@ zypp_perform_execution (PkBackendJob *job, ZYpp::Ptr zypp, PerformType type, gbo snprintf(path_to_cache, len, "/var/local/lib/PackageKit/solutions-cache-%s", job->sender); + try { if (force) zypp->resolver ()->setForceResolve (force); - struct msg_proc_helper transaction_problems; - transaction_problems.problems2 = std::list<struct problem> {}; - // Gather up any dependencies + // Gather up any dependencies pk_backend_job_set_status (job, PK_STATUS_ENUM_DEP_RESOLVE); pk_backend_job_set_percentage(job, 0); zypp->resolver ()->setIgnoreAlreadyRecommended (TRUE); @@ -2178,15 +2314,25 @@ zypp_perform_execution (PkBackendJob *job, ZYpp::Ptr zypp, PerformType type, gbo ResPool pool = ResPool::instance (); + test: if (!zypp->resolver ()->resolvePool ()) { struct backend_job_private *rjob = (struct backend_job_private*) pk_backend_job_get_priv_data (job); + struct msg_proc_helper *transaction_problems; + if (NULL == rjob) { rjob = new (struct backend_job_private)(); pk_backend_job_set_priv_data(job, rjob); + transaction_problems = new struct msg_proc_helper; + transaction_problems->path_to_cache = strdup(path_to_cache); + rjob->job = job; } + else if (rjob->msg_proc_helper){ + + transaction_problems = rjob->msg_proc_helper; + } rjob->to_install = std::list<std::string>(); rjob->to_remove = std::list<std::string>(); rjob->problems = std::list<struct problem> (); @@ -2209,11 +2355,24 @@ zypp_perform_execution (PkBackendJob *job, ZYpp::Ptr zypp, PerformType type, gbo // TODO: SL. S.L. Fill me load_transaction_from_history("Install", path_to_cache, rjob); - transaction_problems.problems = problems; - transaction_problems.it = problems.begin(); - transaction_problems.resolver = zypp->resolver (); - transaction_problems.solution_list = new ProblemSolutionList(); - transaction_problems.problems2 = rjob->problems;//std::list<struct problem> {};//priv->problems; +#if 0 + struct reader_info { + char *buffer; + int curr_old; + int loaded; + int buff_len; + }; +#endif + transaction_problems->reader_info.buffer = NULL; + transaction_problems->reader_info.curr_old = 0; + transaction_problems->reader_info.loaded = 0; + transaction_problems->reader_info.buff_len = 0; + + transaction_problems->problems = problems; + transaction_problems->it = problems.begin(); + transaction_problems->resolver = zypp->resolver (); + transaction_problems->solution_list = new ProblemSolutionList(); + transaction_problems->problems2 = rjob->problems;//std::list<struct problem> {};//priv->problems; ResPool::byKind_iterator itb = pool.byKindBegin (kind); ResPool::byKind_iterator ite = pool.byKindEnd (kind); @@ -2309,9 +2468,28 @@ zypp_perform_execution (PkBackendJob *job, ZYpp::Ptr zypp, PerformType type, gbo // Manual intervention required to resolve dependencies // TODO: Figure out what we need to do with PackageKit // to pull off interactive problem solving. - - - +#if 0 + if (changed && NULL == rjob->msg_proc_helper) { + + if (rjob->sol_it) { + + // delete job->sol_it; + } + rjob->problems = std::list<struct problem> (); + + // rjob->sol_it = new ProblemSolutionList(); + rjob->to_install = to_install; + rjob->to_remove = to_remove; + + + add_resolution_to_zypp(transaction_problems); + /* Save resolution to file */ + save_transaction_to_cache("Install", path_to_cache, transaction_problems, + rjob->to_install, rjob->to_remove); + + goto test; + } +#endif // TODO: Add support for passing request could be handled interactively if (force) { @@ -2343,17 +2521,20 @@ zypp_perform_execution (PkBackendJob *job, ZYpp::Ptr zypp, PerformType type, gbo if (changed) { + + if (rjob->sol_it) { // delete job->sol_it; } - rjob->problems = std::list<struct problem> (); // rjob->sol_it = new ProblemSolutionList(); rjob->to_install = to_install; rjob->to_remove = to_remove; - + job->done = 0; + if (! rjob->msg_proc_helper) { + rjob->msg_proc_helper = transaction_problems; pid_t child_pid; @@ -2391,9 +2572,11 @@ zypp_perform_execution (PkBackendJob *job, ZYpp::Ptr zypp, PerformType type, gbo comm_ch_input = (char*) malloc(length); snprintf(comm_ch_input, length, "%d", fds2[0]); + printf("COMM_CH_OUTPUT: %d COMM_CH_INPUT: %d\n", fds[1], fds2[0]); + execlp(LIBEXECDIR "/dependency-solving-helper", LIBEXECDIR "/dependency-solving-helper", "--comm-channel-input", comm_ch_input,"--comm-channel-output", comm_ch_output, NULL); - write(STDOUT_FILENO, "ERR: Unable to start dependency solver\n", sizeof("Unable to start dependency solver\n") - 1); + write(STDOUT_FILENO, "ERR:\0Unable to start dependency solver\n", sizeof("Unable to start dependency solver\n") - 1); exit(1); } @@ -2413,47 +2596,47 @@ zypp_perform_execution (PkBackendJob *job, ZYpp::Ptr zypp, PerformType type, gbo close(fds[1]); close(fds2[0]); + GError *error; GIOChannel *chann = g_io_channel_unix_new (fds[0]); - g_io_add_watch(chann, G_IO_IN, dependency_handle_selection, &transaction_problems); + g_io_channel_set_encoding(chann, NULL, &error); + g_io_channel_set_buffered(chann, false); + rjob->input_id = g_io_add_watch(chann, G_IO_IN, dependency_handle_selection, (void*)rjob); - output = fds2[1]; + rjob->input = fds[0]; + rjob->output = fds2[1]; input = fds[0]; + write(rjob->output, job->sender, strlen(job->sender) + 1); + + } } { ResolverProblemList::iterator it; ProblemSolutionList::const_iterator sol_it; const char *string; - write(output, job->sender, strlen(job->sender) + 1); - for (it = transaction_problems.problems.begin(); it != transaction_problems.problems.end(); ++it) { + for (it = transaction_problems->problems.begin(); it != transaction_problems->problems.end(); ++it) { string = (*it)->description ().c_str (); - write(output, string, strlen(string)+1); + write(rjob->output, string, strlen(string)+1); for (sol_it = (**it).solutions().begin(); sol_it != (**it).solutions().end(); ++sol_it) { string = (*sol_it)->description ().c_str (); - write(output, string, strlen(string)+1); + write(rjob->output, string, strlen(string)+1); string = (*sol_it)->details ().c_str (); - write(output, string, strlen(string)+1); + write(rjob->output, string, strlen(string)+1); } - write(output, "", sizeof("")); + write(rjob->output, "", sizeof("")); } - write(output, "", sizeof("")); + write(rjob->output, "", sizeof("")); + ret = TRUE; goto exit; } } - else { - add_resolution_to_zypp(&transaction_problems); - /* Save resolution to file */ - save_transaction_to_cache("Install", path_to_cache, &transaction_problems, - rjob->to_install, rjob->to_remove); - - } #if 0 add_resolution_to_zypp(&transaction_problems); @@ -2462,7 +2645,20 @@ zypp_perform_execution (PkBackendJob *job, ZYpp::Ptr zypp, PerformType type, gbo save_transaction_to_cache("Install", path_to_cache, &transaction_problems, priv->to_install, priv->to_remove); #endif + + } + struct backend_job_private *rjob = (struct backend_job_private*) pk_backend_job_get_priv_data (job); + + if (NULL != rjob) { + + //cleaning up + + write(rjob->output, "", sizeof("")); + g_source_unref( g_main_context_find_source_by_id(g_main_context_default(), rjob->input_id)); + close(rjob->input); + close(rjob->output); } + job->done = 1; switch (type) { case INSTALL: pk_backend_job_set_status (job, PK_STATUS_ENUM_INSTALL); diff --git a/helpers/dependency-solving-helper.cpp b/helpers/dependency-solving-helper.cpp index a595c6134..0780cb371 100644 --- a/helpers/dependency-solving-helper.cpp +++ b/helpers/dependency-solving-helper.cpp @@ -2,62 +2,91 @@ #include <stddef.h> #include <unistd.h> #include <string.h> +#include <errno.h> + +#include <unistd.h> +#include <fcntl.h> #include <bonsole_client.h> #include <dbus/dbus.h> -static char *get_record(int fd) + + +struct reader_info { + char *buffer; + int curr_old; + int loaded; + int buff_len; +}; + +struct window { + + xmlNodePtr message; +}; + +struct application { + + struct window window; + int output; + int error_output, messages_output; +}; + +static void reader_info_init(struct reader_info *str) +{ + str->buffer = NULL; + str->curr_old = 0; + str->loaded = 0; + str->buff_len = 0; +} + +static char *get_record(int fd, struct reader_info *info) { - static char *buffer = NULL; - static int curr_old = 0; - static int loaded = 0; - static int buff_len = 0; int count = 0; bool done = false; int curr = 0; - int curr2 = curr_old; + int curr2 = info->curr_old; - while (loaded >= curr2 + 1) { + while (info->loaded >= curr2 + 1) { - if ('\0' == buffer[curr2]) { + if ('\0' == info->buffer[curr2]) { - curr = curr_old ; - curr_old = curr2 + 1; - return &buffer[curr]; + curr = info->curr_old ; + info->curr_old = curr2 + 1; + return &info->buffer[curr]; } ++curr2; } - buff_len += 512; - buffer = (char*)realloc(buffer, buff_len); + info->buff_len += 512; + info->buffer = (char*)realloc(info->buffer, info->buff_len); - if (NULL == buffer) { + if (NULL == info->buffer) { return NULL; } - while ((count = read(fd, &buffer[loaded], buff_len - 1 - loaded)) > 0) { + while ((count = read(fd, &info->buffer[info->loaded], info->buff_len - 1 - info->loaded)) > 0) { - curr = loaded; - loaded += count; - while ('\0' != buffer[curr] && curr < loaded) { + curr = info->loaded; + info->loaded += count; + while ('\0' != info->buffer[curr] && curr < info->loaded) { ++curr; } - if (curr < loaded && '\0' == buffer[curr]) { + if (curr < info->loaded && '\0' == info->buffer[curr]) { done = true; break; } - buff_len += 512; - buffer = (char*)realloc(buffer, buff_len); + info->buff_len += 512; + info->buffer = (char*)realloc(info->buffer, info->buff_len); - if (NULL == buffer) { + if (NULL == info->buffer) { count = 0; break; @@ -67,20 +96,20 @@ static char *get_record(int fd) if (!done && 0 > count) { perror("Error while read from pipe"); - free(buffer); + free(info->buffer); close(fd); return NULL; } - buffer[loaded] = '\0'; + info->buffer[info->loaded] = '\0'; - curr2 = curr_old; - curr_old = curr + 1; - return &buffer[curr2]; + curr2 = info->curr_old; + info->curr_old = curr + 1; + return &info->buffer[curr2]; } -static bool show_solutions(int fd) +static bool show_solutions(int fd, struct reader_info *in_ch_reader) { char *buffer, *prev, *curr, *prev2, *prev3; int length, length2; @@ -99,7 +128,7 @@ static bool show_solutions(int fd) solution = 0; buffer = NULL; - while ((buffer = get_record(fd)) && ('\0' != buffer[0])) { + while ((buffer = get_record(fd, in_ch_reader)) && ('\0' != buffer[0])) { text = xmlNewText(BAD_CAST buffer); @@ -110,7 +139,7 @@ static bool show_solutions(int fd) text = xmlNewNode(NULL, BAD_CAST "br"); xmlAddChild(form, text); - while ((buffer = get_record(fd)) && ('\0' != buffer[0])) { + while ((buffer = get_record(fd, in_ch_reader)) && ('\0' != buffer[0])) { checkbox = xmlNewNode(NULL, BAD_CAST "checkbox"); @@ -122,7 +151,7 @@ static bool show_solutions(int fd) xmlAddChild(form, checkbox); - if ((buffer = get_record(fd)) && ('\0' != buffer[0])) { + if ((buffer = get_record(fd, in_ch_reader)) && ('\0' != buffer[0])) { char *prev = buffer; char *curr = buffer; @@ -181,48 +210,70 @@ static void message_proc(const char *msg__, intptr_t usr_p) int problem, solution; xmlNodePtr root, text, anchor, message, form, checkbox; + struct application *app = (struct application *) usr_p; char *msg_ = bonsole_message_unescape_string(msg__, 0); + if (0 == strncmp("update?", msg_, sizeof("update?") - 1)) { - bonsole_reset_document(nullptr); + //bonsole_reset_document(nullptr); xmlDocPtr a = bonsole_window(nullptr); + root = xmlDocGetRootElement(a); + spec = msg_; + buffer = spec; + length = 0; + while ('\0' != *buffer) { + if ('&' == *buffer) { + ++length; + *buffer = '\0'; + } ++buffer; + } ++length; + buffer = &spec[sizeof("update?") - 1]; + while (0 < length) { + prev = buffer; do { + ++buffer; } while ('_' != *buffer); *buffer = '\0'; + ++buffer; + do { + ++buffer; } while ('=' != *buffer); ++buffer; + if ('\0' != buffer[0] && 0 != strcmp(buffer, "1")) { + --length; do { + ++buffer; } while ('\0' != *buffer); @@ -230,14 +281,19 @@ static void message_proc(const char *msg__, intptr_t usr_p) } while ('\0' != *buffer) { + ++buffer; } + ++buffer; + curr = prev; + prev = buffer; length2 = length - 1; + while (0 < length2) { prev2 = buffer; @@ -246,80 +302,119 @@ static void message_proc(const char *msg__, intptr_t usr_p) do { ++buffer; + } while ('_' != *buffer); + *buffer = '\0'; + ++buffer; if (0 != strcmp(curr, prev2)) { + --length2; do { + ++buffer; } while ('\0' != *buffer); continue; } + do { ++buffer; + } while ('=' != *buffer); ++buffer; + if ('\0' != buffer[0] && 0 != strcmp(buffer, "1")) { --length2; + do { ++buffer; + } while ('\0' != *buffer); ++buffer; + if ('\0' != *buffer) { ++buffer; + } continue; } - message = xmlNewNode(NULL, BAD_CAST "message"); - text = xmlNewText(BAD_CAST "You checked two different solutions for one problem"); - xmlAddChild(message, text); - xmlAddChild(root, message); + //message = xmlNewNode(NULL, BAD_CAST "message"); + + + xmlChar *ent = xmlEncodeEntitiesReentrant(a, BAD_CAST "You checked two different solutions for one problem"); + + xmlNodeSetContent(app->window.message, ent); + + free(ent); bonsole_window_release(nullptr); - show_solutions(usr_p); + + bonsole_flush_changes(nullptr); + + // show_solutions(usr_p); + + + write(app->output, "STOP", sizeof("STOP")); return; } + do { ++buffer; + } while ('\0' != *buffer); int problem_number, solution_number; + problem_number = atoi(curr); + while ('\0' != *curr) ++curr; + prev3 = ++curr; + while ('\0' != *curr && '=' != *curr) ++curr; + *curr = '\0'; - solution_number = atoi(prev3); - //++solution_number; + solution_number = atoi(prev3); free(spec); + int length = (int) (snprintf(NULL, 0, "SELECTION:%d:%d", problem_number, solution_number)) + 1; + char *buffer = (char*) malloc(length); + snprintf(buffer, length, "SELECTION:%c%d:%d", '\0',problem_number, solution_number); + if (1 > write(app->output, buffer, length)) { + + } + + free(buffer); --length; } - - + if (1 > write(app->output, "DONE!", sizeof("DONE!"))) { + + + } + bonsole_window_release(nullptr); - bonsole_flush_changes(nullptr); - + bonsole_flush_changes(nullptr); bonsole_quit_loop(nullptr); + } free(msg_); @@ -328,6 +423,8 @@ static void message_proc(const char *msg__, intptr_t usr_p) int main(int argc, char **argv) { + struct application app; + struct reader_info i_ch_reader; int curr; int input, output, fd; int dup_0, dup_1, dup_2; @@ -361,8 +458,17 @@ int main(int argc, char **argv) exit(1); } } + printf("COMM_CH_OUTPUT: %d COMM_CH_INPUT: %d\n", output, input); + + reader_info_init(&i_ch_reader); + + if (-1 != output) { + + int flags = fcntl(output, F_GETFL, 0); + fcntl(output, F_SETFL, flags | O_NONBLOCK); + } - char *sender = get_record(input); + char *sender = get_record(input, &i_ch_reader); dup_0 = dup(0); dup_1 = dup(1); @@ -537,6 +643,8 @@ int main(int argc, char **argv) if (0 != bonsole_client_init(&argc, argv)) exit(1); } + app.error_output = dup_2; + app.messages_output = dup_1; #if 0 transaction_problems.problems = problems; transaction_problems.it = problems.begin(); @@ -545,11 +653,31 @@ transaction_problems.solution_list = NULL; #endif do { bonsole_reset_document(nullptr); -if (!show_solutions( input)) { +if (!show_solutions( input, &i_ch_reader)) { break; } -bonsole_main_loop(0, message_proc, output); + +xmlNodePtr root, text, message; + +xmlDocPtr a = bonsole_window(nullptr); +root = xmlDocGetRootElement(a); + + +message = xmlNewNode(NULL, BAD_CAST "message"); + +xmlNodeSetContent(message, BAD_CAST " "); + +xmlAddChild(root, message); + +app.window.message = message; +app.output = output; + +bonsole_main_loop(0, message_proc, (intptr_t)(void*) &app); + +if (i_ch_reader.buffer) free(i_ch_reader.buffer); + +reader_info_init(&i_ch_reader); } while (true); #if 0 add_resolution_to_zypp(&transaction_problems); diff --git a/src/pk-backend-job.c b/src/pk-backend-job.c index e6ed7ec6c..168c8e266 100644 --- a/src/pk-backend-job.c +++ b/src/pk-backend-job.c @@ -714,15 +714,19 @@ typedef struct { GDestroyNotify destroy_func; } PkBackendJobThreadHelper; -static gpointer +gpointer pk_backend_job_thread_setup (gpointer thread_data) { PkBackendJobThreadHelper *helper = (PkBackendJobThreadHelper *) thread_data; + helper->job->done = 1; /* run original function with automatic locking */ pk_backend_thread_start (helper->backend, helper->job, helper->func); helper->func (helper->job, helper->job->priv->params, helper->user_data); - pk_backend_job_finished (helper->job); + + // TODO: S.L SL Jeżeli pewne pole wskazuje, że zadanie nie jest zakończone, to nie wykonujemy poniższego wywołania + if (helper->job->done) + pk_backend_job_finished (helper->job); pk_backend_thread_stop (helper->backend, helper->job, helper->func); /* set idle IO priority */ @@ -734,10 +738,15 @@ pk_backend_job_thread_setup (gpointer thread_data) #endif /* destroy helper */ - g_object_unref (helper->job); - if (helper->destroy_func != NULL) - helper->destroy_func (helper->user_data); - g_free (helper); + + // TODO: S.L SL Jeżeli pewne pole wskazuje, że zadanie nie jest zakończone, to nie wykonujemy poniższego wywołania + // Podobnie poniższe 4 linijki + if (helper->job->done) { + g_object_unref (helper->job); + if (helper->destroy_func != NULL) + helper->destroy_func (helper->user_data); + g_free (helper); + } /* no return value */ return NULL; @@ -765,6 +774,7 @@ pk_backend_job_thread_create (PkBackendJob *job, helper->backend = job->priv->backend; helper->func = func; helper->user_data = user_data; + job->helper = (void*) helper; /* create a thread and unref it immediately as we do not need to join() * this at any stage */ @@ -1708,6 +1718,7 @@ pk_backend_job_init (PkBackendJob *job) g_free, (GDestroyNotify) g_object_unref); job->private_data = NULL; + job->done = 0; } /** diff --git a/src/pk-backend-job.h b/src/pk-backend-job.h index b83906059..57006dbd6 100644 --- a/src/pk-backend-job.h +++ b/src/pk-backend-job.h @@ -69,7 +69,9 @@ typedef struct PkBackendJobPrivate *priv; char *sender; - void *private_data; + void *private_data; + char done; + void *helper; } PkBackendJob; typedef struct @@ -257,7 +259,8 @@ gboolean pk_backend_job_get_started (PkBackendJob *job); void *pk_backend_job_get_priv_data (PkBackendJob *job); void pk_backend_job_set_priv_data (PkBackendJob *job, void *a); - +gpointer +pk_backend_job_thread_setup (gpointer thread_data); G_END_DECLS #endif /* __PK_BACKEND_JOB_H */ -- 2.32.0
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor