wayland_backend/rs/server_impl/
client.rs

1use std::{
2    ffi::CString,
3    os::unix::{
4        io::{AsFd, BorrowedFd, OwnedFd, RawFd},
5        net::UnixStream,
6    },
7    sync::Arc,
8};
9
10use crate::{
11    core_interfaces::{WL_CALLBACK_INTERFACE, WL_DISPLAY_INTERFACE, WL_REGISTRY_INTERFACE},
12    debug,
13    protocol::{
14        check_for_signature, same_interface, same_interface_or_anonymous, AllowNull, Argument,
15        ArgumentType, Interface, Message, ObjectInfo, ProtocolError, ANONYMOUS_INTERFACE,
16        INLINE_ARGS,
17    },
18    rs::map::SERVER_ID_LIMIT,
19    types::server::{DisconnectReason, InvalidId},
20};
21
22use smallvec::SmallVec;
23
24use crate::rs::{
25    map::{Object, ObjectMap},
26    socket::{BufferedSocket, Socket},
27    wire::MessageParseError,
28};
29
30use super::{
31    handle::PendingDestructor, registry::Registry, ClientData, ClientId, Credentials, Data,
32    DumbObjectData, GlobalHandler, InnerClientId, InnerGlobalId, InnerObjectId, ObjectData,
33    ObjectId, UninitObjectData,
34};
35
36type ArgSmallVec<Fd> = SmallVec<[Argument<ObjectId, Fd>; INLINE_ARGS]>;
37
38#[repr(u32)]
39#[allow(dead_code)]
40pub(crate) enum DisplayError {
41    InvalidObject = 0,
42    InvalidMethod = 1,
43    NoMemory = 2,
44    Implementation = 3,
45}
46
47#[derive(Debug)]
48pub(crate) struct Client<D: 'static> {
49    socket: BufferedSocket,
50    pub(crate) map: ObjectMap<Data<D>>,
51    debug: bool,
52    last_serial: u32,
53    pub(crate) id: InnerClientId,
54    pub(crate) killed: bool,
55    pub(crate) data: Arc<dyn ClientData>,
56}
57
58impl<D> Client<D> {
59    fn next_serial(&mut self) -> u32 {
60        self.last_serial = self.last_serial.wrapping_add(1);
61        self.last_serial
62    }
63}
64
65impl<D> Client<D> {
66    pub(crate) fn new(
67        stream: UnixStream,
68        id: InnerClientId,
69        debug: bool,
70        data: Arc<dyn ClientData>,
71    ) -> Self {
72        let socket = BufferedSocket::new(Socket::from(stream));
73        let mut map = ObjectMap::new();
74        map.insert_at(
75            1,
76            Object {
77                interface: &WL_DISPLAY_INTERFACE,
78                version: 1,
79                data: Data { user_data: Arc::new(DumbObjectData), serial: 0 },
80            },
81        )
82        .unwrap();
83
84        data.initialized(ClientId { id: id.clone() });
85
86        Self { socket, map, debug, id, killed: false, last_serial: 0, data }
87    }
88
89    pub(crate) fn create_object(
90        &mut self,
91        interface: &'static Interface,
92        version: u32,
93        user_data: Arc<dyn ObjectData<D>>,
94    ) -> InnerObjectId {
95        let serial = self.next_serial();
96        let id = self.map.server_insert_new(Object {
97            interface,
98            version,
99            data: Data { serial, user_data },
100        });
101        InnerObjectId { id, serial, client_id: self.id.clone(), interface }
102    }
103
104    pub(crate) fn destroy_object(
105        &mut self,
106        id: InnerObjectId,
107        pending_destructors: &mut Vec<super::handle::PendingDestructor<D>>,
108    ) -> Result<(), InvalidId> {
109        let object = self.get_object(id.clone())?;
110        pending_destructors.push((object.data.user_data.clone(), self.id.clone(), id.clone()));
111        self.send_delete_id(id.clone());
112        Ok(())
113    }
114
115    pub(crate) fn object_info(&self, id: InnerObjectId) -> Result<ObjectInfo, InvalidId> {
116        let object = self.get_object(id.clone())?;
117        Ok(ObjectInfo { id: id.id, interface: object.interface, version: object.version })
118    }
119
120    pub(crate) fn send_event(
121        &mut self,
122        Message { sender_id: object_id, opcode, args }: Message<ObjectId, RawFd>,
123        pending_destructors: Option<&mut Vec<super::handle::PendingDestructor<D>>>,
124    ) -> Result<(), InvalidId> {
125        if self.killed {
126            return Ok(());
127        }
128        let object = self.get_object(object_id.id.clone())?;
129
130        let message_desc = match object.interface.events.get(opcode as usize) {
131            Some(msg) => msg,
132            None => {
133                panic!(
134                    "Unknown opcode {} for object {}@{}.",
135                    opcode, object.interface.name, object_id.id
136                );
137            }
138        };
139
140        if !check_for_signature(message_desc.signature, &args) {
141            panic!(
142                "Unexpected signature for event {}@{}.{}: expected {:?}, got {:?}.",
143                object.interface.name,
144                object_id.id,
145                message_desc.name,
146                message_desc.signature,
147                args
148            );
149        }
150
151        if self.debug {
152            debug::print_send_message(
153                object.interface.name,
154                object_id.id.id,
155                message_desc.name,
156                &args,
157                false,
158            );
159        }
160
161        let mut msg_args = SmallVec::with_capacity(args.len());
162        let mut arg_interfaces = message_desc.arg_interfaces.iter();
163        for (i, arg) in args.into_iter().enumerate() {
164            msg_args.push(match arg {
165                Argument::Array(a) => Argument::Array(a),
166                Argument::Int(i) => Argument::Int(i),
167                Argument::Uint(u) => Argument::Uint(u),
168                Argument::Str(s) => Argument::Str(s),
169                Argument::Fixed(f) => Argument::Fixed(f),
170                Argument::Fd(f) => Argument::Fd(f),
171                Argument::NewId(o) => {
172                    if o.id.id != 0 {
173                        if o.id.client_id != self.id {
174                            panic!("Attempting to send an event with objects from wrong client.")
175                        }
176                        let object = self.get_object(o.id.clone())?;
177                        let child_interface = match message_desc.child_interface {
178                            Some(iface) => iface,
179                            None => panic!("Trying to send event {}@{}.{} which creates an object without specifying its interface, this is unsupported.", object_id.id.interface.name, object_id.id, message_desc.name),
180                        };
181                        if !same_interface(child_interface, object.interface) {
182                            panic!("Event {}@{}.{} expects a newid argument of interface {} but {} was provided instead.", object.interface.name, object_id.id, message_desc.name, child_interface.name, object.interface.name);
183                        }
184                    } else if !matches!(message_desc.signature[i], ArgumentType::NewId) {
185                        panic!("Request {}@{}.{} expects an non-null newid argument.", object.interface.name, object_id.id, message_desc.name);
186                    }
187                    Argument::Object(o.id.id)
188                },
189                Argument::Object(o) => {
190                    let next_interface = arg_interfaces.next().unwrap();
191                    if o.id.id != 0 {
192                        if o.id.client_id != self.id {
193                            panic!("Attempting to send an event with objects from wrong client.")
194                        }
195                        let arg_object = self.get_object(o.id.clone())?;
196                        if !same_interface_or_anonymous(next_interface, arg_object.interface) {
197                            panic!("Event {}@{}.{} expects an object argument of interface {} but {} was provided instead.", object.interface.name, object_id.id, message_desc.name, next_interface.name, arg_object.interface.name);
198                        }
199                    } else if !matches!(message_desc.signature[i], ArgumentType::Object(AllowNull::Yes)) {
200                            panic!("Request {}@{}.{} expects an non-null object argument.", object.interface.name, object_id.id, message_desc.name);
201                    }
202                    Argument::Object(o.id.id)
203                }
204            });
205        }
206
207        let msg = Message { sender_id: object_id.id.id, opcode, args: msg_args };
208
209        if self.socket.write_message(&msg).is_err() {
210            self.kill(DisconnectReason::ConnectionClosed);
211        }
212
213        // Handle destruction if relevant
214        if message_desc.is_destructor {
215            if let Some(vec) = pending_destructors {
216                vec.push((object.data.user_data.clone(), self.id.clone(), object_id.id.clone()));
217            }
218            self.send_delete_id(object_id.id);
219        }
220
221        Ok(())
222    }
223
224    pub(crate) fn send_delete_id(&mut self, object_id: InnerObjectId) {
225        // We should only send delete_id for objects in the client ID space
226        if object_id.id < SERVER_ID_LIMIT {
227            let msg = message!(1, 1, [Argument::Uint(object_id.id)]);
228            if self.socket.write_message(&msg).is_err() {
229                self.kill(DisconnectReason::ConnectionClosed);
230            }
231        }
232        self.map.remove(object_id.id);
233    }
234
235    pub(crate) fn get_object_data(
236        &self,
237        id: InnerObjectId,
238    ) -> Result<Arc<dyn ObjectData<D>>, InvalidId> {
239        let object = self.get_object(id)?;
240        Ok(object.data.user_data)
241    }
242
243    pub(crate) fn set_object_data(
244        &mut self,
245        id: InnerObjectId,
246        data: Arc<dyn ObjectData<D>>,
247    ) -> Result<(), InvalidId> {
248        self.map
249            .with(id.id, |objdata| {
250                if objdata.data.serial != id.serial {
251                    Err(InvalidId)
252                } else {
253                    objdata.data.user_data = data;
254                    Ok(())
255                }
256            })
257            .unwrap_or(Err(InvalidId))
258    }
259
260    pub(crate) fn post_display_error(&mut self, code: DisplayError, message: CString) {
261        self.post_error(
262            InnerObjectId {
263                id: 1,
264                interface: &WL_DISPLAY_INTERFACE,
265                client_id: self.id.clone(),
266                serial: 0,
267            },
268            code as u32,
269            message,
270        )
271    }
272
273    pub(crate) fn post_error(
274        &mut self,
275        object_id: InnerObjectId,
276        error_code: u32,
277        message: CString,
278    ) {
279        let converted_message = message.to_string_lossy().into();
280        // errors are ignored, as the client will be killed anyway
281        let _ = self.send_event(
282            message!(
283                ObjectId {
284                    id: InnerObjectId {
285                        id: 1,
286                        interface: &WL_DISPLAY_INTERFACE,
287                        client_id: self.id.clone(),
288                        serial: 0
289                    }
290                },
291                0, // wl_display.error
292                [
293                    Argument::Object(ObjectId { id: object_id.clone() }),
294                    Argument::Uint(error_code),
295                    Argument::Str(Some(Box::new(message))),
296                ],
297            ),
298            // wl_display.error is not a destructor, this argument will not be used
299            None,
300        );
301        let _ = self.flush();
302        self.kill(DisconnectReason::ProtocolError(ProtocolError {
303            code: error_code,
304            object_id: object_id.id,
305            object_interface: object_id.interface.name.into(),
306            message: converted_message,
307        }));
308    }
309
310    #[cfg(any(target_os = "linux", target_os = "android"))]
311    pub(crate) fn get_credentials(&self) -> Credentials {
312        let creds =
313            rustix::net::sockopt::socket_peercred(&self.socket).expect("getsockopt failed!?");
314        let pid = rustix::process::Pid::as_raw(Some(creds.pid));
315        Credentials { pid, uid: creds.uid.as_raw(), gid: creds.gid.as_raw() }
316    }
317
318    #[cfg(not(any(target_os = "linux", target_os = "android")))]
319    // for now this only works on linux
320    pub(crate) fn get_credentials(&self) -> Credentials {
321        Credentials { pid: 0, uid: 0, gid: 0 }
322    }
323
324    pub(crate) fn kill(&mut self, reason: DisconnectReason) {
325        self.killed = true;
326        self.data.disconnected(ClientId { id: self.id.clone() }, reason);
327    }
328
329    pub(crate) fn flush(&mut self) -> std::io::Result<()> {
330        self.socket.flush()
331    }
332
333    pub(crate) fn all_objects(&self) -> impl Iterator<Item = ObjectId> + '_ {
334        let client_id = self.id.clone();
335        self.map.all_objects().map(move |(id, obj)| ObjectId {
336            id: InnerObjectId {
337                id,
338                client_id: client_id.clone(),
339                interface: obj.interface,
340                serial: obj.data.serial,
341            },
342        })
343    }
344
345    #[allow(clippy::type_complexity)]
346    pub(crate) fn next_request(
347        &mut self,
348    ) -> std::io::Result<(Message<u32, OwnedFd>, Object<Data<D>>)> {
349        if self.killed {
350            return Err(rustix::io::Errno::PIPE.into());
351        }
352        loop {
353            let map = &self.map;
354            let msg = match self.socket.read_one_message(|id, opcode| {
355                map.find(id)
356                    .and_then(|o| o.interface.requests.get(opcode as usize))
357                    .map(|desc| desc.signature)
358            }) {
359                Ok(msg) => msg,
360                Err(MessageParseError::MissingData) | Err(MessageParseError::MissingFD) => {
361                    // need to read more data
362                    if let Err(e) = self.socket.fill_incoming_buffers() {
363                        if e.kind() != std::io::ErrorKind::WouldBlock {
364                            self.kill(DisconnectReason::ConnectionClosed);
365                        }
366                        return Err(e);
367                    }
368                    continue;
369                }
370                Err(MessageParseError::Malformed) => {
371                    self.kill(DisconnectReason::ConnectionClosed);
372                    return Err(rustix::io::Errno::PROTO.into());
373                }
374            };
375
376            let obj = self.map.find(msg.sender_id).unwrap();
377
378            if self.debug {
379                debug::print_dispatched_message(
380                    obj.interface.name,
381                    msg.sender_id,
382                    obj.interface.requests.get(msg.opcode as usize).unwrap().name,
383                    &msg.args,
384                );
385            }
386
387            return Ok((msg, obj));
388        }
389    }
390
391    pub(crate) fn get_object(&self, id: InnerObjectId) -> Result<Object<Data<D>>, InvalidId> {
392        let object = self.map.find(id.id).ok_or(InvalidId)?;
393        if object.data.serial != id.serial {
394            return Err(InvalidId);
395        }
396        Ok(object)
397    }
398
399    pub(crate) fn object_for_protocol_id(&self, pid: u32) -> Result<InnerObjectId, InvalidId> {
400        let object = self.map.find(pid).ok_or(InvalidId)?;
401        Ok(InnerObjectId {
402            id: pid,
403            client_id: self.id.clone(),
404            serial: object.data.serial,
405            interface: object.interface,
406        })
407    }
408
409    fn queue_all_destructors(&mut self, pending_destructors: &mut Vec<PendingDestructor<D>>) {
410        pending_destructors.extend(self.map.all_objects().map(|(id, obj)| {
411            (
412                obj.data.user_data.clone(),
413                self.id.clone(),
414                InnerObjectId {
415                    id,
416                    serial: obj.data.serial,
417                    client_id: self.id.clone(),
418                    interface: obj.interface,
419                },
420            )
421        }));
422    }
423
424    pub(crate) fn handle_display_request(
425        &mut self,
426        message: Message<u32, OwnedFd>,
427        registry: &mut Registry<D>,
428    ) {
429        match message.opcode {
430            // wl_display.sync(new id wl_callback)
431            0 => {
432                if let [Argument::NewId(new_id)] = message.args[..] {
433                    let serial = self.next_serial();
434                    let callback_obj = Object {
435                        interface: &WL_CALLBACK_INTERFACE,
436                        version: 1,
437                        data: Data { user_data: Arc::new(DumbObjectData), serial },
438                    };
439                    if let Err(()) = self.map.insert_at(new_id, callback_obj) {
440                        self.post_display_error(
441                            DisplayError::InvalidObject,
442                            CString::new(format!("Invalid new_id: {new_id}.")).unwrap(),
443                        );
444                        return;
445                    }
446                    let cb_id = ObjectId {
447                        id: InnerObjectId {
448                            id: new_id,
449                            client_id: self.id.clone(),
450                            serial,
451                            interface: &WL_CALLBACK_INTERFACE,
452                        },
453                    };
454                    // send wl_callback.done(0) this callback does not have any meaningful destructor to run, we can ignore it
455                    self.send_event(message!(cb_id, 0, [Argument::Uint(0)]), None).unwrap();
456                } else {
457                    unreachable!()
458                }
459            }
460            // wl_display.get_registry(new id wl_registry)
461            1 => {
462                if let [Argument::NewId(new_id)] = message.args[..] {
463                    let serial = self.next_serial();
464                    let registry_obj = Object {
465                        interface: &WL_REGISTRY_INTERFACE,
466                        version: 1,
467                        data: Data { user_data: Arc::new(DumbObjectData), serial },
468                    };
469                    let registry_id = InnerObjectId {
470                        id: new_id,
471                        serial,
472                        client_id: self.id.clone(),
473                        interface: &WL_REGISTRY_INTERFACE,
474                    };
475                    if let Err(()) = self.map.insert_at(new_id, registry_obj) {
476                        self.post_display_error(
477                            DisplayError::InvalidObject,
478                            CString::new(format!("Invalid new_id: {new_id}.")).unwrap(),
479                        );
480                        return;
481                    }
482                    let _ = registry.new_registry(registry_id, self);
483                } else {
484                    unreachable!()
485                }
486            }
487            _ => {
488                // unkown opcode, kill the client
489                self.post_display_error(
490                    DisplayError::InvalidMethod,
491                    CString::new(format!(
492                        "Unknown opcode {} for interface wl_display.",
493                        message.opcode
494                    ))
495                    .unwrap(),
496                );
497            }
498        }
499    }
500
501    #[allow(clippy::type_complexity)]
502    pub(crate) fn handle_registry_request(
503        &mut self,
504        message: Message<u32, OwnedFd>,
505        registry: &mut Registry<D>,
506    ) -> Option<(InnerClientId, InnerGlobalId, InnerObjectId, Arc<dyn GlobalHandler<D>>)> {
507        match message.opcode {
508            // wl_registry.bind(uint name, str interface, uint version, new id)
509            0 => {
510                if let [Argument::Uint(name), Argument::Str(Some(ref interface_name)), Argument::Uint(version), Argument::NewId(new_id)] =
511                    message.args[..]
512                {
513                    if let Some((interface, global_id, handler)) =
514                        registry.check_bind(self, name, interface_name, version)
515                    {
516                        let serial = self.next_serial();
517                        let object = Object {
518                            interface,
519                            version,
520                            data: Data { serial, user_data: Arc::new(UninitObjectData) },
521                        };
522                        if let Err(()) = self.map.insert_at(new_id, object) {
523                            self.post_display_error(
524                                DisplayError::InvalidObject,
525                                CString::new(format!("Invalid new_id: {new_id}.")).unwrap(),
526                            );
527                            return None;
528                        }
529                        Some((
530                            self.id.clone(),
531                            global_id,
532                            InnerObjectId {
533                                id: new_id,
534                                client_id: self.id.clone(),
535                                interface,
536                                serial,
537                            },
538                            handler.clone(),
539                        ))
540                    } else {
541                        self.post_display_error(
542                            DisplayError::InvalidObject,
543                            CString::new(format!(
544                                "Invalid binding of {} version {} for global {}.",
545                                interface_name.to_string_lossy(),
546                                version,
547                                name
548                            ))
549                            .unwrap(),
550                        );
551                        None
552                    }
553                } else {
554                    unreachable!()
555                }
556            }
557            _ => {
558                // unkown opcode, kill the client
559                self.post_display_error(
560                    DisplayError::InvalidMethod,
561                    CString::new(format!(
562                        "Unknown opcode {} for interface wl_registry.",
563                        message.opcode
564                    ))
565                    .unwrap(),
566                );
567                None
568            }
569        }
570    }
571
572    pub(crate) fn process_request(
573        &mut self,
574        object: &Object<Data<D>>,
575        message: Message<u32, OwnedFd>,
576    ) -> Option<(ArgSmallVec<OwnedFd>, bool, Option<InnerObjectId>)> {
577        let message_desc = object.interface.requests.get(message.opcode as usize).unwrap();
578
579        if message_desc.since > object.version {
580            self.post_display_error(
581                DisplayError::InvalidMethod,
582                CString::new(format!(
583                    "invalid method {} (since {} < {}), object {}#{}",
584                    message.opcode,
585                    object.version,
586                    message_desc.since,
587                    object.interface.name,
588                    message.sender_id
589                ))
590                .unwrap(),
591            );
592            return None;
593        }
594
595        // Convert the arguments and create the new object if applicable
596        let mut new_args = SmallVec::with_capacity(message.args.len());
597        let mut arg_interfaces = message_desc.arg_interfaces.iter();
598        let mut created_id = None;
599        for (i, arg) in message.args.into_iter().enumerate() {
600            new_args.push(match arg {
601                Argument::Array(a) => Argument::Array(a),
602                Argument::Int(i) => Argument::Int(i),
603                Argument::Uint(u) => Argument::Uint(u),
604                Argument::Str(s) => Argument::Str(s),
605                Argument::Fixed(f) => Argument::Fixed(f),
606                Argument::Fd(f) => Argument::Fd(f),
607                Argument::Object(o) => {
608                    let next_interface = arg_interfaces.next();
609                    if o != 0 {
610                        // Lookup the object to make the appropriate Id
611                        let obj = match self.map.find(o) {
612                            Some(o) => o,
613                            None => {
614                                self.post_display_error(
615                                    DisplayError::InvalidObject,
616                                    CString::new(format!("Unknown id: {o}.")).unwrap()
617                                );
618                                return None;
619                            }
620                        };
621                        if let Some(next_interface) = next_interface {
622                            if !same_interface_or_anonymous(next_interface, obj.interface) {
623                                self.post_display_error(
624                                    DisplayError::InvalidObject,
625                                    CString::new(format!(
626                                        "Invalid object {} in request {}.{}: expected {} but got {}.",
627                                        o,
628                                        object.interface.name,
629                                        message_desc.name,
630                                        next_interface.name,
631                                        obj.interface.name,
632                                    )).unwrap()
633                                );
634                                return None;
635                            }
636                        }
637                        Argument::Object(ObjectId { id: InnerObjectId { id: o, client_id: self.id.clone(), serial: obj.data.serial, interface: obj.interface }})
638                    } else if matches!(message_desc.signature[i], ArgumentType::Object(AllowNull::Yes)) {
639                        Argument::Object(ObjectId { id: InnerObjectId { id: 0, client_id: self.id.clone(), serial: 0, interface: &ANONYMOUS_INTERFACE }})
640                    } else {
641                        self.post_display_error(
642                            DisplayError::InvalidObject,
643                            CString::new(format!(
644                                "Invalid null object in request {}.{}.",
645                                object.interface.name,
646                                message_desc.name,
647                            )).unwrap()
648                        );
649                        return None;
650                    }
651                }
652                Argument::NewId(new_id) => {
653                    // An object should be created
654                    let child_interface = match message_desc.child_interface {
655                        Some(iface) => iface,
656                        None => panic!("Received request {}@{}.{} which creates an object without specifying its interface, this is unsupported.", object.interface.name, message.sender_id, message_desc.name),
657                    };
658
659                    let child_udata = Arc::new(UninitObjectData);
660
661                    let child_obj = Object {
662                        interface: child_interface,
663                        version: object.version,
664                        data: Data {
665                            user_data: child_udata,
666                            serial: self.next_serial(),
667                        }
668                    };
669
670                    let child_id = InnerObjectId { id: new_id, client_id: self.id.clone(), serial: child_obj.data.serial, interface: child_obj.interface };
671                    created_id = Some(child_id.clone());
672
673                    if let Err(()) = self.map.insert_at(new_id, child_obj) {
674                        // abort parsing, this is an unrecoverable error
675                        self.post_display_error(
676                            DisplayError::InvalidObject,
677                            CString::new(format!("Invalid new_id: {new_id}.")).unwrap()
678                        );
679                        return None;
680                    }
681
682                    Argument::NewId(ObjectId { id: child_id })
683                }
684            });
685        }
686        Some((new_args, message_desc.is_destructor, created_id))
687    }
688}
689
690impl<D> AsFd for Client<D> {
691    fn as_fd(&self) -> BorrowedFd<'_> {
692        self.socket.as_fd()
693    }
694}
695
696#[derive(Debug)]
697pub(crate) struct ClientStore<D: 'static> {
698    clients: Vec<Option<Client<D>>>,
699    last_serial: u32,
700    debug: bool,
701}
702
703impl<D> ClientStore<D> {
704    pub(crate) fn new(debug: bool) -> Self {
705        Self { clients: Vec::new(), last_serial: 0, debug }
706    }
707
708    pub(crate) fn create_client(
709        &mut self,
710        stream: UnixStream,
711        data: Arc<dyn ClientData>,
712    ) -> InnerClientId {
713        let serial = self.next_serial();
714        // Find the next free place
715        let (id, place) = match self.clients.iter_mut().enumerate().find(|(_, c)| c.is_none()) {
716            Some((id, place)) => (id, place),
717            None => {
718                self.clients.push(None);
719                (self.clients.len() - 1, self.clients.last_mut().unwrap())
720            }
721        };
722
723        let id = InnerClientId { id: id as u32, serial };
724
725        *place = Some(Client::new(stream, id.clone(), self.debug, data));
726
727        id
728    }
729
730    pub(crate) fn get_client(&self, id: InnerClientId) -> Result<&Client<D>, InvalidId> {
731        match self.clients.get(id.id as usize) {
732            Some(Some(client)) if client.id == id => Ok(client),
733            _ => Err(InvalidId),
734        }
735    }
736
737    pub(crate) fn get_client_mut(
738        &mut self,
739        id: InnerClientId,
740    ) -> Result<&mut Client<D>, InvalidId> {
741        match self.clients.get_mut(id.id as usize) {
742            Some(&mut Some(ref mut client)) if client.id == id => Ok(client),
743            _ => Err(InvalidId),
744        }
745    }
746
747    pub(crate) fn cleanup(
748        &mut self,
749        pending_destructors: &mut Vec<PendingDestructor<D>>,
750    ) -> SmallVec<[Client<D>; 1]> {
751        let mut cleaned = SmallVec::new();
752        for place in &mut self.clients {
753            if place.as_ref().map(|client| client.killed).unwrap_or(false) {
754                // Remove the client from the store and flush it one last time before dropping it
755                let mut client = place.take().unwrap();
756                client.queue_all_destructors(pending_destructors);
757                let _ = client.flush();
758                cleaned.push(client);
759            }
760        }
761        cleaned
762    }
763
764    fn next_serial(&mut self) -> u32 {
765        self.last_serial = self.last_serial.wrapping_add(1);
766        self.last_serial
767    }
768
769    pub(crate) fn clients_mut(&mut self) -> impl Iterator<Item = &mut Client<D>> {
770        self.clients.iter_mut().flat_map(|o| o.as_mut()).filter(|c| !c.killed)
771    }
772
773    pub(crate) fn all_clients_id(&self) -> impl Iterator<Item = ClientId> + '_ {
774        self.clients.iter().flat_map(|opt| {
775            opt.as_ref().filter(|c| !c.killed).map(|client| ClientId { id: client.id.clone() })
776        })
777    }
778}