static void messaging_server_exec_room_bdcast(ServerData *server, User *user, char* msg){ //Skipp invalid data if(user == NULL || msg == NULL){ fprintf(stdout, "[ERR] Invalid message '%s' from '%s'\n", user->login, msg); return; } //Recover room where user is Room* room = list_get_where(&(server->list_rooms), user->room, room_match_name); if(room == NULL){ fprintf(stderr, "[ERR] Unable to recover the room of user '%s'\n", user->login); messaging_send_error(user->socket, MSG_ERR_GENERAL, "Unable to send message in room."); return; } fprintf(stdout, "[CHAT] '%s': '%s' send '%s'\n", user->room, user->login, msg); room_broadcast_message(room, user, msg); }
void session_run_with_nick(struct room *room, struct lock *roomLock, struct reader *reader, struct writer *writer, struct string_buffer *nick) /*@ requires locked(roomLock, ?roomLockId, room_ctor(room), currentThread, _) &*& lockset(currentThread, cons(roomLockId, nil)) &*& room(room) &*& reader(reader) &*& writer(writer) &*& string_buffer(nick, _); @*/ /*@ ensures [_]lock(roomLock, roomLockId, room_ctor(room)) &*& lockset(currentThread, nil) &*& reader(reader) &*& writer(writer) &*& string_buffer(nick, _); @*/ { struct member *member = 0; struct string_buffer *joinMessage = create_string_buffer(); string_buffer_append_string_buffer(joinMessage, nick); string_buffer_append_string(joinMessage, " has joined the room."); room_broadcast_message(room, joinMessage); string_buffer_dispose(joinMessage); { struct string_buffer *nickCopy = string_buffer_copy(nick); //@ open room(room); member = malloc(sizeof(struct member)); if (member == 0) { abort(); } member->nick = nickCopy; member->writer = writer; //@ split_fraction member_writer(member, _) by 1/2; //@ close member(member); //@ assert room->members |-> ?list &*& lseg(list, 0, ?members, @member); member->next = room->members; room->members = member; //@ open member_next(member, _); //@ close lseg(member, 0, cons(member, members), @member); //@ assert [_]room->ghost_list_id |-> ?id; //@ split_fraction room_ghost_list_id(room, id); //@ ghost_list_add(id, member); //@ close room(room); } //@ close room_ctor(room)(); lock_release(roomLock); //@ leak [_]lock(roomLock, roomLockId, room_ctor(room)); { bool eof = false; struct string_buffer *message = create_string_buffer(); while (!eof) //@ invariant reader(reader) &*& string_buffer(nick, _) &*& string_buffer(message, _) &*& [_]lock(roomLock, roomLockId, room_ctor(room)) &*& lockset(currentThread, nil); { eof = reader_read_line(reader, message); if (eof) { } else { lock_acquire(roomLock); //@ open room_ctor(room)(); { struct string_buffer *fullMessage = create_string_buffer(); string_buffer_append_string_buffer(fullMessage, nick); string_buffer_append_string(fullMessage, " says: "); string_buffer_append_string_buffer(fullMessage, message); room_broadcast_message(room, fullMessage); string_buffer_dispose(fullMessage); } //@ close room_ctor(room)(); lock_release(roomLock); } } string_buffer_dispose(message); } lock_acquire(roomLock); //@ open room_ctor(room)(); //@ open room(room); { struct member *membersList = room->members; //@ open room_members(room, _); //@ assert lseg(membersList, 0, ?members, @member); //@ assert [_]ghost_list_member_handle(?id, ?d); //@ ghost_list_member_handle_lemma(id, d); lseg_remove(&room->members, member); //@ assert pointer(&room->members, ?list); //@ close room_members(room, list); //@ assert pointer((void *)member, ?memberNext); //@ close member_next(member, memberNext); } //@ assert ghost_list(?id, _); //@ ghost_list_remove(id, member); //@ close room(room); { struct string_buffer *goodbyeMessage = create_string_buffer(); string_buffer_append_string_buffer(goodbyeMessage, nick); string_buffer_append_string(goodbyeMessage, " left the room."); room_broadcast_message(room, goodbyeMessage); string_buffer_dispose(goodbyeMessage); } //@ close room_ctor(room)(); lock_release(roomLock); //@ open member(member); string_buffer_dispose(member->nick); free(member); }