Changeset 5483a52daf9dca6aa6cbfafc7d6d050456d49dd3

Show
Ignore:
Timestamp:
09/26/11 05:03:57 (20 months ago)
Author:
Nedko Arnaudov <nedko@…>
Children:
f42b4fbef76944dc292983208ef62e144ab7031f
Parents:
3af230cad5cdbb19784ffc8bac1a404eeac7c707
git-committer:
Nedko Arnaudov <nedko@arnaudov.name> / 2011-09-26T05:03:57Z+0300
Message:

ladishd: async app supervisor save. async studio and project save.

Location:
daemon
Files:
6 modified

Legend:

Unmodified
Added
Removed
  • daemon/app_supervisor.c

    r6aa44e9 r5483a52  
    999999} 
    10001000 
    1001 void ladish_app_supervisor_save(ladish_app_supervisor_handle supervisor_handle) 
     1001void 
     1002ladish_app_supervisor_save( 
     1003  ladish_app_supervisor_handle supervisor_handle, 
     1004  void * context, 
     1005  ladish_save_complete_callback callback) 
    10021006{ 
    10031007  struct list_head * node_ptr; 
     
    10201024    ladish_app_initiate_save(app_ptr); 
    10211025  } 
     1026 
     1027  callback(context, true); 
    10221028} 
    10231029 
  • daemon/app_supervisor.h

    r6aa44e9 r5483a52  
    8787 
    8888/** 
     89 * Type of function that is called when save is complete 
     90 * 
     91 * @param[in] context User defined context that was supplied to ladish_app_supervisor_save() 
     92 * @param[in] success Whether save was successfull or not 
     93 */ 
     94typedef void (* ladish_save_complete_callback)(void * context, bool success); 
     95 
     96/** 
    8997 * Check whether app level string is valid. 
    9098 * 
     
    195203 * 
    196204 * @param[in] supervisor_handle supervisor object handle 
     205 * @param[in] context User defined context to be supplied when callback supplied throuth @c callback parameter is called 
     206 * @param[in] callback Callback to call when save is complete 
    197207 */ 
    198208void 
    199209ladish_app_supervisor_save( 
    200   ladish_app_supervisor_handle supervisor_handle); 
     210  ladish_app_supervisor_handle supervisor_handle, 
     211  void * context, 
     212  ladish_save_complete_callback callback); 
    201213 
    202214/** 
  • daemon/cmd_save_project.c

    r8bc41a2 r5483a52  
    3737  char * project_dir; 
    3838  char * project_name; 
     39  bool done; 
     40  bool success; 
    3941}; 
    4042 
    4143#define cmd_ptr ((struct ladish_command_save_project *)command_context) 
     44 
     45void ladish_room_project_complete(void * command_context, bool success) 
     46{ 
     47  cmd_ptr->done = true; 
     48  cmd_ptr->success = success; 
     49 
     50  if (!success) 
     51  { 
     52    ladish_notify_simple(LADISH_NOTIFY_URGENCY_HIGH, "Project save failed", LADISH_CHECK_LOG_TEXT); 
     53  } 
     54} 
    4255 
    4356static bool run(void * command_context) 
     
    4558  ladish_room_handle room; 
    4659 
    47   ASSERT(cmd_ptr->command.state == LADISH_COMMAND_STATE_PENDING); 
     60  if (cmd_ptr->command.state == LADISH_COMMAND_STATE_WAITING) 
     61  { 
     62    if (!cmd_ptr->done) 
     63    { 
     64      return true; 
     65    } 
     66 
     67    cmd_ptr->command.state = LADISH_COMMAND_STATE_DONE; 
     68    return cmd_ptr->success; 
     69  } 
     70 
     71  if (cmd_ptr->command.state != LADISH_COMMAND_STATE_PENDING) 
     72  { 
     73    ASSERT_NO_PASS; 
     74    return false; 
     75  } 
    4876 
    4977  room = ladish_studio_find_room_by_uuid(cmd_ptr->room_uuid); 
     
    5583  } 
    5684 
    57   ladish_room_save_project(room, cmd_ptr->project_dir, cmd_ptr->project_name); 
     85  cmd_ptr->command.state = LADISH_COMMAND_STATE_WAITING; 
    5886 
    59   cmd_ptr->command.state = LADISH_COMMAND_STATE_DONE; 
     87  ladish_room_save_project(room, cmd_ptr->project_dir, cmd_ptr->project_name, cmd_ptr, ladish_room_project_complete); 
    6088 
    6189  return true; 
     
    110138  cmd_ptr->project_dir = project_dir_dup; 
    111139  cmd_ptr->project_name = project_name_dup; 
     140  cmd_ptr->done = false; 
     141  cmd_ptr->success = true; 
    112142 
    113143  if (!ladish_cqueue_add_command(queue_ptr, &cmd_ptr->command)) 
  • daemon/cmd_save_studio.c

    r0266594 r5483a52  
    185185  struct ladish_command command; 
    186186  char * studio_name; 
     187  bool done; 
     188  bool success; 
    187189}; 
    188190 
    189 #define cmd_ptr ((struct ladish_command_save_studio *)command_context) 
    190  
    191 static bool run(void * command_context) 
     191static bool ladish_save_studio_xml(struct ladish_command_save_studio * cmd_ptr) 
    192192{ 
    193193  struct list_head * node_ptr; 
     
    204204  bool renaming; 
    205205 
    206   ASSERT(cmd_ptr->command.state == LADISH_COMMAND_STATE_PENDING); 
    207  
    208206  time(&timestamp); 
    209207  ctime_r(&timestamp, timestamp_str); 
    210208  timestamp_str[24] = 0; 
    211  
    212   ret = false; 
    213  
    214   ladish_app_supervisor_save(g_studio.app_supervisor); 
    215  
    216   if (!ladish_studio_is_started()) 
    217   { 
    218     log_error("Cannot save not-started studio"); 
    219     ladish_notify_simple(LADISH_NOTIFY_URGENCY_HIGH, "Cannot save not-started studio", NULL); 
    220     goto exit; 
    221   } 
    222  
    223   ladish_check_integrity(); 
    224209 
    225210  if (!ladish_studio_compose_filename(cmd_ptr->studio_name, &filename, &bak_filename)) 
     
    409394  g_studio.automatic = false;   /* even if it was automatic, it is not anymore because it is saved */ 
    410395 
    411   cmd_ptr->command.state = LADISH_COMMAND_STATE_DONE; 
    412  
    413396  ret = true; 
    414397 
     
    450433 
    451434exit: 
    452   if (!ret) 
    453   { 
    454     ladish_notify_simple(LADISH_NOTIFY_URGENCY_HIGH, "Studio save failed", LADISH_CHECK_LOG_TEXT); 
    455   } 
    456  
    457435  return ret; 
     436} 
     437 
     438#define cmd_ptr ((struct ladish_command_save_studio *)context) 
     439 
     440static void ladish_studio_apps_save_complete(void * context, bool success) 
     441{ 
     442  ASSERT(cmd_ptr->command.state == LADISH_COMMAND_STATE_WAITING); 
     443 
     444  if (!success) 
     445  { 
     446    log_info("Studio apps save failed"); 
     447    goto fail; 
     448  } 
     449 
     450  log_info("Studio apps saved successfully"); 
     451  if (ladish_save_studio_xml(cmd_ptr)) 
     452  { 
     453    goto done; 
     454  } 
     455 
     456fail: 
     457  ladish_notify_simple(LADISH_NOTIFY_URGENCY_HIGH, "Studio save failed", LADISH_CHECK_LOG_TEXT); 
     458  cmd_ptr->success = false; 
     459 
     460done: 
     461  cmd_ptr->done = true; 
     462  return; 
     463} 
     464 
     465#undef cmd_ptr 
     466 
     467#define cmd_ptr ((struct ladish_command_save_studio *)command_context) 
     468 
     469static bool run(void * command_context) 
     470{ 
     471  if (cmd_ptr->command.state == LADISH_COMMAND_STATE_WAITING) 
     472  { 
     473    if (!cmd_ptr->done) 
     474    { 
     475      return true; 
     476    } 
     477 
     478    cmd_ptr->command.state = LADISH_COMMAND_STATE_DONE; 
     479    return cmd_ptr->success; 
     480  } 
     481 
     482  if (cmd_ptr->command.state != LADISH_COMMAND_STATE_PENDING) 
     483  { 
     484    ASSERT_NO_PASS; 
     485    return false; 
     486  } 
     487 
     488  if (!ladish_studio_is_started()) 
     489  { 
     490    log_error("Cannot save not-started studio"); 
     491    ladish_notify_simple(LADISH_NOTIFY_URGENCY_HIGH, "Cannot save not-started studio", NULL); 
     492    return false; 
     493  } 
     494 
     495  ladish_check_integrity(); 
     496 
     497  cmd_ptr->command.state = LADISH_COMMAND_STATE_WAITING; 
     498 
     499  ladish_app_supervisor_save(g_studio.app_supervisor, cmd_ptr, ladish_studio_apps_save_complete); 
     500 
     501  return true; 
    458502} 
    459503 
     
    491535  cmd_ptr->command.destructor = destructor; 
    492536  cmd_ptr->studio_name = studio_name_dup; 
     537  cmd_ptr->done = false; 
     538  cmd_ptr->success = true; 
    493539 
    494540  if (!ladish_cqueue_add_command(queue_ptr, &cmd_ptr->command)) 
  • daemon/room.h

    r3ac3105 r5483a52  
    33 * LADI Session Handler (ladish) 
    44 * 
    5  * Copyright (C) 2010 Nedko Arnaudov <nedko@arnaudov.name> 
     5 * Copyright (C) 2010,2011 Nedko Arnaudov <nedko@arnaudov.name> 
    66 * 
    77 ************************************************************************** 
     
    8787  uint32_t flags); 
    8888 
    89 bool ladish_room_save_project(ladish_room_handle room_handle, const char * project_dir, const char * project_name); 
     89typedef void (* ladish_room_save_complete_callback)(void * context, bool success); 
     90 
     91bool 
     92ladish_room_save_project( 
     93  ladish_room_handle room_handle, 
     94  const char * project_dir, 
     95  const char * project_name, 
     96  void * context, 
     97  ladish_room_save_complete_callback callback); 
     98 
    9099bool ladish_room_unload_project(ladish_room_handle room_handle); 
    91100bool ladish_room_load_project(ladish_room_handle room_handle, const char * project_dir); 
  • daemon/room_save.c

    r0266594 r5483a52  
    4242#define DEFAULT_PROJECT_BASE_DIR_LEN ((size_t)(sizeof(DEFAULT_PROJECT_BASE_DIR) - 1)) 
    4343 
    44 static bool ladish_room_save_project_do(struct ladish_room * room_ptr) 
     44struct ladish_room_save_context 
     45{ 
     46  struct ladish_room * room; 
     47  char * project_dir; 
     48  char * project_name; 
     49  char * old_project_dir; 
     50  char * old_project_name; 
     51 
     52  void * context; 
     53  ladish_room_save_complete_callback callback; 
     54}; 
     55 
     56static void ladish_room_save_context_destroy(struct ladish_room_save_context * ctx_ptr) 
     57{ 
     58  if (ctx_ptr->project_name != NULL && ctx_ptr->project_name != ctx_ptr->room->project_name) 
     59  { 
     60    free(ctx_ptr->room->project_name); 
     61  } 
     62 
     63  if (ctx_ptr->project_dir != NULL && ctx_ptr->project_dir != ctx_ptr->room->project_dir) 
     64  { 
     65    free(ctx_ptr->room->project_dir); 
     66  } 
     67 
     68  /* free strings that are allocated and stored only in the stack */ 
     69  if (ctx_ptr->project_name != NULL && ctx_ptr->project_name != ctx_ptr->room->project_name) 
     70  { 
     71    free(ctx_ptr->project_name); 
     72  } 
     73 
     74  if (ctx_ptr->project_dir != NULL && ctx_ptr->project_dir != ctx_ptr->room->project_dir) 
     75  { 
     76    free(ctx_ptr->project_dir); 
     77  } 
     78 
     79  free(ctx_ptr); 
     80} 
     81 
     82static void ladish_room_save_complete(struct ladish_room_save_context * ctx_ptr, bool success) 
     83{ 
     84  if (!success) 
     85  { 
     86    ctx_ptr->room->project_name = ctx_ptr->old_project_name; 
     87    ctx_ptr->room->project_dir = ctx_ptr->old_project_dir; 
     88  } 
     89 
     90  ctx_ptr->callback(ctx_ptr->context, success); 
     91 
     92  ladish_room_save_context_destroy(ctx_ptr); 
     93} 
     94 
     95static bool ladish_room_save_project_xml(struct ladish_room * room_ptr) 
    4596{ 
    4697  bool ret; 
     
    52103  int fd; 
    53104 
    54   log_info("Saving project '%s' in room '%s' to '%s'", room_ptr->project_name, room_ptr->name, room_ptr->project_dir); 
    55  
    56   ladish_check_integrity(); 
    57  
    58105  time(&timestamp); 
    59106  ctime_r(&timestamp, timestamp_str); 
     
    62109  ret = false; 
    63110 
    64   if (!ensure_dir_exist(room_ptr->project_dir, 0777)) 
    65   { 
    66     goto exit; 
    67   } 
    68  
    69111  uuid_generate(room_ptr->project_uuid); /* TODO: the uuid should be changed on "save as" but not on "rename" */ 
    70112  uuid_unparse(room_ptr->project_uuid, uuid_str); 
     
    234276    goto close; 
    235277  } 
    236  
    237   ladish_app_supervisor_save(room_ptr->app_supervisor); 
    238  
    239   ladish_room_emit_project_properties_changed(room_ptr); 
    240278 
    241279  ret = true; 
     
    251289} 
    252290 
     291#define ctx_ptr ((struct ladish_room_save_context *)context) 
     292 
     293static void ladish_room_apps_save_complete(void * context, bool success) 
     294{ 
     295  log_info("Project '%s' apps in room '%s' %s to '%s'", ctx_ptr->room->project_name, ctx_ptr->room->name, success ? "saved successfully" : "failed to save", ctx_ptr->room->project_dir); 
     296 
     297  if (!success) 
     298  { 
     299    ladish_room_save_complete(ctx_ptr, false); 
     300    return; 
     301  } 
     302 
     303  if (!ladish_room_save_project_xml(ctx_ptr->room)) 
     304  { 
     305    ladish_room_save_complete(ctx_ptr, false); 
     306    /* TODO: try to rollback apps save stage */ 
     307    return; 
     308  } 
     309 
     310  ladish_room_emit_project_properties_changed(ctx_ptr->room); 
     311 
     312  ctx_ptr->room->project_state = ROOM_PROJECT_STATE_LOADED; 
     313 
     314  ladish_room_save_complete(ctx_ptr, true); 
     315} 
     316 
     317#undef ctx_ptr 
     318 
     319static bool ladish_room_save_project_do(struct ladish_room_save_context * ctx_ptr) 
     320{ 
     321  log_info("Saving project '%s' in room '%s' to '%s'", ctx_ptr->room->project_name, ctx_ptr->room->name, ctx_ptr->room->project_dir); 
     322 
     323  ladish_check_integrity(); 
     324 
     325  if (!ensure_dir_exist(ctx_ptr->room->project_dir, 0777)) 
     326  { 
     327    goto fail; 
     328  } 
     329 
     330  ladish_app_supervisor_save(ctx_ptr->room->app_supervisor, ctx_ptr, ladish_room_apps_save_complete); 
     331 
     332  return true; 
     333 
     334fail: 
     335  ladish_room_save_complete(ctx_ptr, false); 
     336  return false; 
     337} 
     338 
    253339/* TODO: base dir must be a runtime setting */ 
    254340char * compose_project_dir_from_name(const char * project_name) 
     
    281367  ladish_room_handle room_handle, 
    282368  const char * project_dir_param, 
    283   const char * project_name_param) 
    284 { 
     369  const char * project_name_param, 
     370  void * context, 
     371  ladish_room_save_complete_callback callback) 
     372{ 
     373  struct ladish_room_save_context * ctx_ptr; 
    285374  bool first_time; 
    286375  bool dir_supplied; 
    287376  bool name_supplied; 
    288   char * project_dir; 
    289   char * project_name; 
    290   char * old_project_dir; 
    291   char * old_project_name; 
    292377  char * buffer; 
    293378  bool ret; 
    294379 
    295380  ret = false; 
    296   project_name = NULL; 
    297   project_dir = NULL; 
     381 
     382  ctx_ptr = malloc(sizeof(struct ladish_room_save_context)); 
     383  if (ctx_ptr == NULL) 
     384  { 
     385    log_error("malloc() failed to allocate memory for room save context struct"); 
     386    goto fail; 
     387  } 
     388 
     389  ctx_ptr->room = room_ptr; 
     390  ctx_ptr->project_name = NULL; 
     391  ctx_ptr->project_dir = NULL; 
     392  ctx_ptr->context = context; 
     393  ctx_ptr->callback = callback; 
    298394 
    299395  /* project has either both name and dir no none of them */ 
     
    309405    { 
    310406      log_error("Cannot save unnamed project in room '%s'", room_ptr->name); 
    311       goto exit; 
     407      goto destroy_ctx; 
    312408    } 
    313409 
    314410    if (dir_supplied && name_supplied) 
    315411    { 
    316       project_dir = strdup(project_dir_param); 
    317       project_name = strdup(project_name_param); 
     412      ctx_ptr->project_dir = strdup(project_dir_param); 
     413      ctx_ptr->project_name = strdup(project_name_param); 
    318414    } 
    319415    else if (dir_supplied) 
     
    325421      { 
    326422        log_error("strdup() failed for project dir"); 
    327         goto exit; 
     423        goto destroy_ctx; 
    328424      } 
    329425 
    330       project_name = basename(buffer); 
    331       log_info("Project name for dir '%s' will be '%s'", project_dir_param, project_name); 
    332       project_name = strdup(project_name); 
     426      ctx_ptr->project_name = basename(buffer); 
     427      log_info("Project name for dir '%s' will be '%s'", project_dir_param, ctx_ptr->project_name); 
     428      ctx_ptr->project_name = strdup(ctx_ptr->project_name); 
    333429      free(buffer); 
    334       project_dir = strdup(project_dir_param); /* buffer cannot be used because it may be modified by basename() */ 
     430      ctx_ptr->project_dir = strdup(project_dir_param); /* buffer cannot be used because it may be modified by basename() */ 
    335431    } 
    336432    else if (name_supplied) 
     
    338434      ASSERT(!dir_supplied); 
    339435 
    340       project_dir = compose_project_dir_from_name(project_name_param); 
    341       if (!project_dir) 
     436      ctx_ptr->project_dir = compose_project_dir_from_name(project_name_param); 
     437      if (ctx_ptr->project_dir == NULL) 
    342438      { 
    343         goto exit; 
     439        goto destroy_ctx; 
    344440      } 
    345441 
    346       log_info("Project dir for name '%s' will be '%s'", project_name_param, project_dir); 
    347  
    348       project_name = strdup(project_name_param); 
     442      log_info("Project dir for name '%s' will be '%s'", project_name_param, ctx_ptr->project_dir); 
     443 
     444      ctx_ptr->project_name = strdup(project_name_param); 
    349445    } 
    350446    else 
    351447    { 
    352448      ASSERT_NO_PASS; 
    353       goto exit; 
    354     } 
    355  
    356     ladish_app_supervisor_set_directory(room_ptr->app_supervisor, project_dir); 
     449      goto destroy_ctx; 
     450    } 
     451 
     452    ladish_app_supervisor_set_directory(room_ptr->app_supervisor, ctx_ptr->project_dir); 
    357453  } 
    358454  else 
     
    361457    ASSERT(room_ptr->project_dir != NULL); 
    362458 
    363     project_name = name_supplied ? strdup(project_name_param) : room_ptr->project_name; 
    364     project_dir = dir_supplied ? strdup(project_dir_param) : room_ptr->project_dir; 
    365   } 
    366  
    367   if (project_name == NULL || project_dir == NULL) 
     459    ctx_ptr->project_name = name_supplied ? strdup(project_name_param) : room_ptr->project_name; 
     460    ctx_ptr->project_dir = dir_supplied ? strdup(project_dir_param) : room_ptr->project_dir; 
     461  } 
     462 
     463  if (ctx_ptr->project_name == NULL || ctx_ptr->project_dir == NULL) 
    368464  { 
    369465    log_error("strdup() failed for project name or dir"); 
    370     goto exit; 
    371   } 
    372  
    373   old_project_dir = room_ptr->project_dir; 
    374   old_project_name = room_ptr->project_name; 
    375   room_ptr->project_name = project_name; 
    376   room_ptr->project_dir = project_dir; 
    377   ret = ladish_room_save_project_do(room_ptr); 
    378   if (!ret) 
    379   { 
    380     room_ptr->project_name = old_project_name; 
    381     room_ptr->project_dir = old_project_dir; 
    382   } 
    383   else 
    384   { 
    385     room_ptr->project_state = ROOM_PROJECT_STATE_LOADED; 
    386   } 
    387  
    388 exit: 
    389   if (project_name != NULL && project_name != room_ptr->project_name) 
    390   { 
    391     free(room_ptr->project_name); 
    392   } 
    393  
    394   if (project_dir != NULL && project_dir != room_ptr->project_dir) 
    395   { 
    396     free(room_ptr->project_dir); 
    397   } 
    398  
    399   /* free strings that are allocated and stored only in the stack */ 
    400   if (project_name != NULL && project_name != room_ptr->project_name) 
    401   { 
    402     free(project_name); 
    403   } 
    404   if (project_dir != NULL && project_dir != room_ptr->project_dir) 
    405   { 
    406     free(project_dir); 
    407   } 
    408  
    409   return ret; 
     466    goto destroy_ctx; 
     467  } 
     468 
     469  ctx_ptr->old_project_dir = room_ptr->project_dir; 
     470  ctx_ptr->old_project_name = room_ptr->project_name; 
     471  room_ptr->project_name = ctx_ptr->project_name; 
     472  room_ptr->project_dir = ctx_ptr->project_dir; 
     473 
     474  return ladish_room_save_project_do(ctx_ptr); 
     475 
     476destroy_ctx: 
     477  ladish_room_save_context_destroy(ctx_ptr); 
     478fail: 
     479  return false; 
    410480} 
    411481